Motivations
Nghiên cứu có tên Spread of risk across financial markets: better to invest in the peripheries của Pozzi et al. (2013) đã chỉ ra một hướng mới trong việc thiết lập danh mục đầu tư. Sử dụng dữ liệu về giá của các cổ phiếu niêm yết trên sàn American Stock Exchange (AMEX) từ 1981 đến 2010 các tác giả này đã chỉ ra rằng performance của danh mục đầu tư từ các cổ phiếu vùng ngoại vi (Peripheral Stocks) là tốt hơn performance của danh mục đầu tư từ các cổ phiếu trung tâm (Central Stocks) căn cứ vào signal-to-noise ratio (tỉ số này là một trường hợp riêng của Sharpe Ratio khi mà lợi tức của tài sản phi rủi ro bằng không).
Các cổ phiếu được phân thành hai thái cực (ngoại vi nhất - trung tâm nhất) dựa trên một tiêu chuẩn có tên là Hybird Centralily (HC) tính từ mạng PMFG (Planar Maximally Filtered Graphs) đề xuất bởi Tumminello et al. (2005).
Trong post này chúng ta sẽ sử dụng dữ liệu lịch sử các cổ phiếu AMEX trong khoảng thời gian từ 2018-01-01 đến 2021-10-20 để:
Dựa trên follow đã được sử dụng bởi Pozzi et al. (2013), so sánh portfolio performance từ 6 cổ phiếu trung tâm nhất và 6 cổ phiếu ngoại vi nhất dựa trên TMFG Network đề xuất bởi Massara et al. (2016).
Kiểm tra để xem các insights trong nghiên cứu của Pozzi et al. (2013) có lặp lại với chính dữ liệu các cổ phiếu AMEX hay không trong khoảng thời gian 2018-01-01 đến 2021-10-20.
So sánh cấu trúc hai nhóm danh mục đầu tư được thiết lập từ TMFG và PMFG Network.
TMFG Network for Portfolio Selection
Trước hết lấy dữ liệu về các mã AMEX trong khoảng thời gian 2018-01-01 đến 2021-10-20 rồi lấy ra 100 mã có vốn hóa thị trường lớn nhất:
Thực hiện một số bước tiền xử lí cho bộ dữ liệu thô:
Tính HC từ TMFG Network với windown size = 250 để list ra nhóm 6 cổ phiếu trung tâm nhất và nhóm 6 cổ phiếu ngoại vi nhất như cách làm của Pozzi et al. (2013):
Chúng ta có thể xem qua xu hướng biến động về giá của nhóm cổ phiếu ngoại vi nhất (Figure 1):

Và nhóm cổ phiếu trung tâm nhất (Figure 2):

Viết hàm có tên compare_performance_top6() so sánh portfolio performance cho hai kiểu danh mục đầu tư với Days following the investment day = 100,.., 250:
So sánh portfolio performance của hai danh mục sau các thời điểm 100,.., 250 ngày kể từ ngày danh mục đầu tư được thiết lập (Figure 3):

Từ Figure 3 có thẻ thấy rằng tại phần lớn mốc thời gian được xét (sau ngày hai danh mục đầu tư được thiết lập) thì danh mục đầu tư cấu thành từ 6 cổ phiếu trung tâm nhất (đường màu đỏ) có performance thấp hơn so với đường màu xanh (danh mục đầu tư cấu thành từ 6 cổ phiếu ngoại vi nhất). Kết quả này là tương tự với những insights của Pozzi et al. (2013). Kết luận này cũng có thể được rút ra theo cách khác là so sánh average của Sharpe Ratio của hai danh mục đầu tư như sau:
Table 1: Portfolio Performance by Average Signal-to-noise Ratio
Central |
0.0029868 |
0.0198129 |
0.1506899 |
151 |
Peripheral |
0.0012136 |
0.0063170 |
0.1924963 |
151 |
Danh mục đầu tư các cổ phiếu ngoại vi có Average Signal-to-noise Ratio là 0.1924962, cao hơn 0.1506899 của danh mục đầu tư các cổ phiếu trung tâm.
PMFG Network for Portfolio Selection
Để kiểm tra xem các khám phá của Pozzi et al. (2013) có còn đúng không với dữ liệu của các cổ phiếu AMEX trong khoảng thời gian từ 2018-01-01 đến 2021-10-20 trước hết sử dụng hàm PMFG được viết bởi Alex Christensen:
Sử dụng hàm này để tính HC measure:
Có thể thấy hai cách tiếp cận sẽ tạo ra những kết quả tương đối khác biệt về HC:
## ACU ACY AE AEF AMPE ASXC
## 0.290 0.235 0.296 0.735 0.405 0.743
## ACU ACY AE AEF AMPE ASXC
## 0.259 0.460 0.246 0.702 0.316 0.685
List ra 6 cổ phiếu trung tâm nhất - ngoại vi nhất theo PMFG Network:
Có thể thấy 6 cổ phiếu trung tâm nhất từ hai cách tiếp cận này là khác nhau:
## [1] "ENX" "INFU" "LODE" "MLSS" "MTNB" "RVP"
## [1] "INFU" "ISDR" "LODE" "MLSS" "UAVS" "XTNT"
Nhưng nhóm 6 cổ phiếu ngoại vi lại khá giống nhau:
## [1] "BCV" "CET" "CRF" "GLO" "LNG" "NHS"
## [1] "BCV" "CET" "EVV" "GLO" "LNG" "NHS"
So sánh portfolio performance của hai kiểu danh mục đầu tư từ PMFG Network (Figure 4):

Figure 4 cho thấy danh mục đầu tư ngoại vi (đường màu xanh) vẫn có performance tốt hơn. Tương tự các tiêu chí đánh giá performance của hai danh mục được cho ở Table 2 dưới đây:
Table 2: Portfolio Performance by Average Signal-to-noise Ratio
Central |
0.0021861 |
0.0206124 |
0.1058679 |
151 |
Peripheral |
0.0011682 |
0.0056795 |
0.2062286 |
151 |
Conclusion
Từ kết quả thực nghiệm với bộ dữ liệu 100 cổ phiếu AMEX có vốn hóa thị trường lớn nhất có thể rút ra vài kết luận quan trọng sau:
Các khám phá chính của Pozzi et al. (2013) vẫn lặp lại với dữ liệu cập nhật hơn. Cụ thể, performance của danh mục đầu tư cấu thành từ các cổ phiếu ngoại vi nhất vẫn tốt hơn performance của danh mục đầu tư cấu thành từ các cổ phiếu trung tâm nhất bất kể cách tiếp cận là TMFG hay PMFG.
Hybird Centrality (HC) từ hai cách tiếp cận TMFG và PMFG là tương đối khác biệt. Tuy nhiên cấu trúc danh mục đầu tư ngoại vi lại khá giống nhau: giống nhau 5 trong tổng số 6 cổ phiếu.
Bibliography
F. Pozzi, T. Di Matteo, and T. Aste. Spread of risk across financial markets: Better to invest in the peripheries. Scientific Reports, 3:1665, 2013. URL https://doi.org/10.1038/srep01665. [p428].
F. Pozzi. Filtering financial networks and optimal portfolio selection. Ph.D. Thesis (The Australian National University, Canberra, 2013).
T. Di Matteo, F. Pozzi, T. Aste. The use of dynamical networks to detect the hierarchical organization of financial market sectors. European Physical Journal B 73, 3–11 (2010)
D. Y. Kenett, M. Tumminello, A. Madi, G. Gur-Gershgoren, R. N. Mantegna, and E. Ben-Jacob. Dominating clasp of the financial sector revealed by partial correlation analysis of the stock market. PloS one, 5(12):e15032, 2010. URL https://doi.org/10.1371/journal.pone.0015032. [p426].
W. Barfuss, G. P. Massara, T. Di Matteo, and T. Aste. Parsimonious modeling with information filtering networks. Physical Review E, 94(6):062306, 2016. URL https://doi.org/10.1103/PhysRevE.94. 062306. [p423, 424, 425].
LS0tDQp0aXRsZTogJ1RyaWFuZ3VsYXRlZCBNYXhpbWFsbHkgRmlsdGVyZWQgR3JhcGggKFRNRkcpIGZvciBQb3J0Zm9saW8gU2VsZWN0aW9uJw0KYXV0aG9yOiAnQXV0aG9yOiBOZ3V5ZW4gQ2hpIER1bmcnDQpzdWJ0aXRsZTogIlIgRmluYW5jZSBTZXJpZXMiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICAjIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGhpZ2hsaWdodDogemVuYnVybg0KICAgICMgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogImZsYXRseSINCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCi0tLQ0KDQpgYGB7ciBzZXR1cCxpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIGNhY2hlID0gVFJVRSkNCg0KYGBgDQoNCiMgTW90aXZhdGlvbnMNCg0KTmdoacOqbiBj4bupdSBjw7MgdMOqbiBbU3ByZWFkIG9mIHJpc2sgYWNyb3NzIGZpbmFuY2lhbCBtYXJrZXRzOiBiZXR0ZXIgdG8gaW52ZXN0IGluIHRoZSBwZXJpcGhlcmllc10oaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9hcnRpY2xlcy9zcmVwMDE2NjUjOn46dGV4dD1XZSUyMGZvdW5kJTIwdGhhdCUyMGludmVzdGluZyUyMGluLHRvJTIwaW52ZXN0bWVudHMlMjBpbiUyMGNlbnRyYWwlMjBzdG9ja3MuKSBj4bunYSBQb3p6aSBldCBhbC4gKDIwMTMpIMSRw6MgY2jhu4kgcmEgbeG7mXQgaMaw4bubbmcgbeG7m2kgdHJvbmcgdmnhu4djIHRoaeG6v3QgbOG6rXAgZGFuaCBt4bulYyDEkeG6p3UgdMawLiBT4butIGThu6VuZyBk4buvIGxp4buHdSB24buBIGdpw6EgY+G7p2EgY8OhYyBj4buVIHBoaeG6v3UgbmnDqm0geeG6v3QgdHLDqm4gc8OgbiBBbWVyaWNhbiBTdG9jayBFeGNoYW5nZSAoQU1FWCkgdOG7qyAxOTgxIMSR4bq/biAyMDEwIGPDoWMgdMOhYyBnaeG6oyBuw6B5IMSRw6MgY2jhu4kgcmEgcuG6sW5nIHBlcmZvcm1hbmNlIGPhu6dhIGRhbmggbeG7pWMgxJHhuqd1IHTGsCB04burIGPDoWMgY+G7lSBwaGnhur91IHbDuW5nIG5nb+G6oWkgdmkgKFBlcmlwaGVyYWwgU3RvY2tzKSBsw6AgdOG7kXQgaMahbiBwZXJmb3JtYW5jZSBj4bunYSBkYW5oIG3hu6VjIMSR4bqndSB0xrAgdOG7qyBjw6FjIGPhu5UgcGhp4bq/dSB0cnVuZyB0w6JtIChDZW50cmFsIFN0b2NrcykgY8SDbiBj4bupIHbDoG8gc2lnbmFsLXRvLW5vaXNlIHJhdGlvICh04buJIHPhu5EgbsOgeSBsw6AgbeG7mXQgdHLGsOG7nW5nIGjhu6NwIHJpw6puZyBj4bunYSBTaGFycGUgUmF0aW8ga2hpIG3DoCBs4bujaSB04bupYyBj4bunYSB0w6BpIHPhuqNuIHBoaSBy4bunaSBybyBi4bqxbmcga2jDtG5nKS4gDQoNCg0KQ8OhYyBj4buVIHBoaeG6v3UgxJHGsOG7o2MgcGjDom4gdGjDoG5oIGhhaSB0aMOhaSBj4buxYyAobmdv4bqhaSB2aSBuaOG6pXQgLSB0cnVuZyB0w6JtIG5o4bqldCkgZOG7sWEgdHLDqm4gbeG7mXQgdGnDqnUgY2h14bqpbiBjw7MgdMOqbiBsw6AgSHliaXJkIENlbnRyYWxpbHkgKEhDKSB0w61uaCB04burIG3huqFuZyBQTUZHIChQbGFuYXIgTWF4aW1hbGx5IEZpbHRlcmVkIEdyYXBocykgxJHhu4EgeHXhuqV0IGLhu59pIFR1bW1pbmVsbG8gZXQgYWwuICgyMDA1KS4gDQoNCg0KVHJvbmcgcG9zdCBuw6B5IGNow7puZyB0YSBz4bq9IHPhu60gZOG7pW5nIGThu68gbGnhu4d1IGzhu4tjaCBz4butIGPDoWMgY+G7lSBwaGnhur91IEFNRVggdHJvbmcga2hv4bqjbmcgdGjhu51pIGdpYW4gdOG7qyAyMDE4LTAxLTAxIMSR4bq/biAyMDIxLTEwLTIwIMSR4buDOiANCg0KLSBE4buxYSB0csOqbiBmb2xsb3cgxJHDoyDEkcaw4bujYyBz4butIGThu6VuZyBi4bufaSBQb3p6aSBldCBhbC4gKDIwMTMpLCBzbyBzw6FuaCBwb3J0Zm9saW8gcGVyZm9ybWFuY2UgdOG7qyA2IGPhu5UgcGhp4bq/dSB0cnVuZyB0w6JtIG5o4bqldCB2w6AgNiBj4buVIHBoaeG6v3Ugbmdv4bqhaSB2aSBuaOG6pXQgZOG7sWEgdHLDqm4gVE1GRyBOZXR3b3JrIMSR4buBIHh14bqldCBi4bufaSBNYXNzYXJhIGV0IGFsLiAoMjAxNikuIA0KDQotIEtp4buDbSB0cmEgxJHhu4MgeGVtIGPDoWMgaW5zaWdodHMgdHJvbmcgbmdoacOqbiBj4bupdSBj4bunYSBQb3p6aSBldCBhbC4gKDIwMTMpIGPDsyBs4bq3cCBs4bqhaSB24bubaSBjaMOtbmggZOG7ryBsaeG7h3UgY8OhYyBj4buVIHBoaeG6v3UgQU1FWCBoYXkga2jDtG5nIHRyb25nIGtob+G6o25nIHRo4budaSBnaWFuIDIwMTgtMDEtMDEgxJHhur9uIDIwMjEtMTAtMjAuIA0KLSBTbyBzw6FuaCBj4bqldSB0csO6YyBoYWkgbmjDs20gZGFuaCBt4bulYyDEkeG6p3UgdMawIMSRxrDhu6NjIHRoaeG6v3QgbOG6rXAgdOG7qyBUTUZHIHbDoCBQTUZHIE5ldHdvcmsuIA0KDQojIFRNRkcgTmV0d29yayBmb3IgUG9ydGZvbGlvIFNlbGVjdGlvbg0KDQpUcsaw4bubYyBo4bq/dCBs4bqleSBk4buvIGxp4buHdSB24buBIGPDoWMgbcOjIEFNRVggdHJvbmcga2hv4bqjbmcgdGjhu51pIGdpYW4gMjAxOC0wMS0wMSDEkeG6v24gMjAyMS0xMC0yMCBy4buTaSBs4bqleSByYSAxMDAgbcOjIGPDsyB24buRbiBow7NhIHRo4buLIHRyxrDhu51uZyBs4bubbiBuaOG6pXQ6IA0KDQpgYGB7cn0NCiMgQ2xlYXIgUiBlbnZpcm9ubWVudDogDQoNCnJtKGxpc3QgPSBscygpKQ0KDQojIEdldCBhbGwgc3ltYm9scyBmcm9tIEFtZXJpY2FuIFN0b2NrIEV4Y2hhbmdlIE1hcmtldCAoQU1FWCk6IA0KDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCg0KIyBHZXQgYWxsIEFNRVggc3ltYm9sczogDQoNCmxpYnJhcnkodGlkeXF1YW50KQ0KDQp0cV9leGNoYW5nZSgiQU1FWCIpIC0+IGFtZXhfc3ltYm9scw0KDQojIFRvcCAxMDAgVVMgY29tcGFuaWVzIGJ5IG1hcmtldCBjYXBpdGFsaXphdGlvbjogDQoNCmFtZXhfc3ltYm9scyAlPiUgDQogIGZpbHRlcihjb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIikgJT4lIA0KICB0b3BfbihuID0gMTAwLCB3dCA9IG1hcmtldC5jYXApIC0+IHRvcDEwMF91c19hbWV4X2NvbXBhbmllcw0KDQojIEdldCBwcmljZSBkYXRhOiANCg0KdHFfZ2V0KHRvcDEwMF91c19hbWV4X2NvbXBhbmllcyRzeW1ib2wsIA0KICAgICAgIGdldCA9ICJzdG9jay5wcmljZXMiLCANCiAgICAgICBmcm9tID0gIjIwMTgtMDEtMDEiLCANCiAgICAgICB0byA9ICIyMDIxLTEwLTIwIikgLT4gdG9wMTAwX3VzX2FtZXhfcHJpY2VzDQpgYGANCg0KVGjhu7FjIGhp4buHbiBt4buZdCBz4buRIGLGsOG7m2MgdGnhu4FuIHjhu60gbMOtIGNobyBi4buZIGThu68gbGnhu4d1IHRow7Q6IA0KDQpgYGB7cn0NCiMgU3ltYm9scyB3aXRoIG1pc3NpbmcgZGF0YSBwb2ludDogDQoNCnRvcDEwMF91c19hbWV4X3ByaWNlcyAlPiUgDQogIHNlbGVjdChzeW1ib2wsIGRhdGUsIGFkanVzdGVkKSAlPiUgDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzeW1ib2wsIHZhbHVlc19mcm9tID0gYWRqdXN0ZWQpIC0+IHByaWNlc19sb25nX2Zvcm0NCg0Kc2FwcGx5KHByaWNlc19sb25nX2Zvcm0sIGZ1bmN0aW9uKHgpIHtzdW0oaXMubmEoeCkpfSkgLT4gbWlzc2luZ19zeW1ib2xzDQoNCm1pc3Npbmdfc3ltYm9sc1ttaXNzaW5nX3N5bWJvbHMgIT0gMF0gJT4lIG5hbWVzKCkgLT4gc3ltYm9sc19taXNzaW5nDQoNCiMgUmVtb3ZlIG1pc3Npbmcgc3ltYm9scyBhbmQgc2VsZWN0IHNvbWUgY29sdW1uczogDQoNCnRvcDEwMF91c19hbWV4X3ByaWNlcyAlPiUgDQogIGZpbHRlcighc3ltYm9sICVpbiUgc3ltYm9sc19taXNzaW5nKSAlPiUgDQogIHNlbGVjdChzeW1ib2wsIGRhdGUsIGFkanVzdGVkKSAtPiBwcmljZXNfbG9uZ19mb3JtX2Z1bGwNCg0KIyBDYWxjdWxhdGUgZGFpbHkgcmV0dXJucyBhbmQgY29udmVydCB0byB3aWRlIGZvcm06IA0KDQpwcmljZXNfbG9uZ19mb3JtX2Z1bGwgJT4lIA0KICBncm91cF9ieShzeW1ib2wpICU+JSANCiAgbXV0YXRlKGxhZzEgPSBsYWcoYWRqdXN0ZWQsIG4gPSAxTCkpICU+JSANCiAgZmlsdGVyKCFpcy5uYShsYWcxKSkgJT4lIA0KICBtdXRhdGUoZGFpbHlfcmV0dXJuID0gKGFkanVzdGVkIC0gbGFnMSkgLyBsYWcxKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHNlbGVjdChzeW1ib2wsIGRhdGUsIGRhaWx5X3JldHVybikgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3ltYm9sLCB2YWx1ZXNfZnJvbSA9IGRhaWx5X3JldHVybikgLT4gcmV0dXJuc193aWRlDQpgYGANCg0KVMOtbmggSEMgdOG7qyBUTUZHIE5ldHdvcmsgduG7m2kgd2luZG93biBzaXplID0gMjUwIMSR4buDIGxpc3QgcmEgbmjDs20gNiBj4buVIHBoaeG6v3UgdHJ1bmcgdMOibSBuaOG6pXQgdsOgIG5ow7NtIDYgY+G7lSBwaGnhur91IG5nb+G6oWkgdmkgbmjhuqV0IG5oxrAgY8OhY2ggbMOgbSBj4bunYSBQb3p6aSBldCBhbC4gKDIwMTMpOiAgDQoNCmBgYHtyfQ0KIyBQcmVwYXJlIGRhdGEgZm9yIGNhbGN1bGF0aW5nIEh5YmlyZCBDZW50cmFsaXR5OiANCg0Kd2luZG93X3NpemUgPC0gMjUwDQoNCnJldHVybnNfd2lkZSAlPiUgc2xpY2UoMTp3aW5kb3dfc2l6ZSkgLT4gcmV0dXJuX3dpZGVfbWluaQ0KDQplbmRfZGF0ZSA8LSBtYXgocmV0dXJuX3dpZGVfbWluaSRkYXRlKQ0KDQpyZXR1cm5fd2lkZV9taW5pICU+JSBzZWxlY3QoLWRhdGUpIC0+IHJldHVybl93aWRlX21pbmlfMjUwDQoNCiM9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQojICAgICAgIFRNRkcgTmV0d29yaw0KIz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCg0KIyBDb25zdHJ1Y3QgVE1GRyBuZXR3b3JrOiANCg0KbGlicmFyeShOZXR3b3JrVG9vbGJveCkNCg0KVE1GRyhyZXR1cm5fd2lkZV9taW5pXzI1MCkgLT4gdG1mZ19vYmplY3RzDQoNCiMgQ2FsY3VsYXRlIEh5YmlyZCBDZW50cmFsaXR5IE1lYXN1cmU6IA0KDQpoeWJyaWQodG1mZ19vYmplY3RzJEEpIC0+IGhjX21lYXN1cmUNCg0KIyBUb3AgNiBjZW50cmFsIGFuZCBwZXJpcGhlcmFsIHN5bWJvbHM6IA0KDQpkYXRhLmZyYW1lKGhjX21lYXN1cmUpIC0+IGNlbnRyYWxfcGVyX2RmDQoNCmNlbnRyYWxfcGVyX2RmICU+JSBtdXRhdGUoc3ltYm9sID0gcm93Lm5hbWVzKC4pKSAtPiBjZW50cmFsX3Blcl9kZg0KDQpjZW50cmFsX3Blcl9kZiAlPiUgDQogIHRvcF9uKG4gPSA2LCB3dCA9IGhjX21lYXN1cmUpICU+JSANCiAgc2xpY2UoMTo2KSAlPiUgDQogIHB1bGwoc3ltYm9sKSAtPiB0b3A2X3BlcmlwaGVyYWwNCg0KY2VudHJhbF9wZXJfZGYgJT4lIA0KICB0b3BfbihuID0gNiwgd3QgPSAtaGNfbWVhc3VyZSkgJT4lIA0KICBzbGljZSgxOjYpICU+JSANCiAgcHVsbChzeW1ib2wpIC0+IHRvcDZfY2VudHJhbA0KYGBgDQoNCkNow7puZyB0YSBjw7MgdGjhu4MgeGVtIHF1YSB4dSBoxrDhu5tuZyBiaeG6v24gxJHhu5luZyB24buBIGdpw6EgY+G7p2EgbmjDs20gY+G7lSBwaGnhur91IG5nb+G6oWkgdmkgbmjhuqV0IChGaWd1cmUgMSk6IA0KDQpgYGB7cn0NCiMgUHJpY2UgdHJlbmQgZm9yIHRvcCA2IHBlcmlwaGVyYWwgc3ltYm9sczogDQoNCnByaWNlc19sb25nX2Zvcm1fZnVsbCAlPiUgDQogIGZpbHRlcihzeW1ib2wgJWluJSB0b3A2X3BlcmlwaGVyYWwpICU+JSANCiAgZmlsdGVyKGRhdGUgPiBlbmRfZGF0ZSkgJT4lIA0KICBncm91cF9ieShzeW1ib2wpICU+JSANCiAgc2xpY2UoMTAwOjI1MCkgJT4lIA0KICBnZ3Bsb3QoYWVzKGRhdGUsIGFkanVzdGVkLCBjb2xvciA9IHN5bWJvbCkpICsgDQogIGdlb21fbGluZShzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICBmYWNldF93cmFwKH4gc3ltYm9sLCBzY2FsZXMgPSAiZnJlZSIpICsgDQogIGxhYnMoeCA9IE5VTEwsIA0KICAgICAgIHkgPSAiUHJpY2UiLCANCiAgICAgICB0aXRsZSA9ICJGaWd1cmUgMTogSGlzdG9yaWNhbCBQcmljZSBmb3IgVG9wLTYtUGVyaXBoZXJhbCBTdG9ja3MsIFRNRkcgTmV0d29yayIpDQpgYGANCg0KVsOgIG5ow7NtIGPhu5UgcGhp4bq/dSB0cnVuZyB0w6JtIG5o4bqldCAoRmlndXJlIDIpOiANCg0KYGBge3J9DQojIFByaWNlIHRyZW5kIGZvciB0b3AgNiBjZW50cmFsIHN5bWJvbHM6IA0KDQpwcmljZXNfbG9uZ19mb3JtX2Z1bGwgJT4lIA0KICBmaWx0ZXIoc3ltYm9sICVpbiUgdG9wNl9jZW50cmFsKSAlPiUgDQogIGZpbHRlcihkYXRlID4gZW5kX2RhdGUpICU+JSANCiAgZ3JvdXBfYnkoc3ltYm9sKSAlPiUgDQogIHNsaWNlKDEwMDoyNTApICU+JSANCiAgZ2dwbG90KGFlcyhkYXRlLCBhZGp1c3RlZCwgY29sb3IgPSBzeW1ib2wpKSArIA0KICBnZW9tX2xpbmUoc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyANCiAgZmFjZXRfd3JhcCh+IHN5bWJvbCwgc2NhbGVzID0gImZyZWUiKSArIA0KICBsYWJzKHggPSBOVUxMLCANCiAgICAgICB5ID0gIlByaWNlIiwgDQogICAgICAgdGl0bGUgPSAiRmlndXJlIDI6IEhpc3RvcmljYWwgUHJpY2UgZm9yIFRvcC02LUNlbnRyYWwgU3RvY2tzLCBUTUZHIE5ldHdvcmsiKQ0KYGBgDQoNCg0KVmnhur90IGjDoG0gY8OzIHTDqm4gKipjb21wYXJlX3BlcmZvcm1hbmNlX3RvcDYoKSoqIHNvIHPDoW5oIHBvcnRmb2xpbyBwZXJmb3JtYW5jZSBjaG8gaGFpIGtp4buDdSBkYW5oIG3hu6VjIMSR4bqndSB0xrAgduG7m2kgRGF5cyBmb2xsb3dpbmcgdGhlIGludmVzdG1lbnQgZGF5ID0gMTAwLC4uLCAyNTA6IA0KDQpgYGB7cn0NCiMgRnVuY3Rpb24gY29tcGFyZXMgcG9ydGZvbGlvIHBlcmZvcm1hbmNlOiANCg0KY29tcGFyZV9wZXJmb3JtYW5jZV90b3A2IDwtIGZ1bmN0aW9uKC4uLikgew0KICANCiAgIz09PT09PT09PT09PT09PT09PT09PT09PT0NCiAgIyAgUG9ydGZvbGlvIFBlcmZvcm1hbmNlDQogICM9PT09PT09PT09PT09PT09PT09PT09PT09DQogIA0KICANCiAgIyBGdW50aW9uIGNhbGN1bGF0ZXMgcmlzayBhbmQgcmV0dXJuIGZvciBwZXJpcGhlcmFsIHBvcnRmb2xpbzogDQogIA0KICByaXNrX3JldHVybl90b3A1X3BlcmlwaGVyYWxfcG9ydGZvbGlvIDwtIGZ1bmN0aW9uKG5fbmV4dF9tYXJrZXRfZGF5KSB7DQogICAgDQogICAgIyBuX25leHRfbWFya2V0X2RheSA8LSAxMDANCiAgICANCiAgICByZXR1cm5zX3dpZGUgJT4lIA0KICAgICAgc2VsZWN0KGMoImRhdGUiLCB0b3A2X3BlcmlwaGVyYWwpKSAlPiUgDQogICAgICBmaWx0ZXIoZGF0ZSA+IGVuZF9kYXRlKSAlPiUgDQogICAgICBzbGljZSgxOm5fbmV4dF9tYXJrZXRfZGF5KSAtPiByZXR1cm5zX3dpZGVfbmV4dA0KICAgIA0KICAgICMgTWVhbiByZXR1cm46IA0KICAgIA0KICAgIG11IDwtIGNvbE1lYW5zKHJldHVybnNfd2lkZV9uZXh0JT4lIHNlbGVjdCgtZGF0ZSksIG5hLnJtID0gVFJVRSkgDQogICAgDQogICAgIyBDb3ZhcmlhbmNlIG1hdHJpeDogDQogICAgDQogICAgc2lnbWFfbWF0cml4IDwtIGNvdihyZXR1cm5zX3dpZGVfbmV4dCAlPiUgc2VsZWN0KC1kYXRlKSwgdXNlID0gImNvbXBsZXRlLm9icyIpDQogICAgDQogICAgIyBBc3NldCB3ZWlnaHRzOiANCiAgICANCiAgICBuX3N0b2NrcyA8LSBsZW5ndGgobXUpDQogICAgDQogICAgd2VpZ2h0cyA8LSByZXAoMSAvIG5fc3RvY2tzLCBuX3N0b2NrcykNCiAgICANCiAgICAjIFBvcnRmb2xpbyByZXR1cm46IA0KICAgIA0KICAgIG11X3BvcnQgPC0gY3Jvc3Nwcm9kKHdlaWdodHMsIG11KSAlPiUgYXMubnVtZXJpYygpDQogICAgDQogICAgIyBQb3J0Zm9saW8gcmlzazogDQogICAgDQogICAgc2lnMl9wb3J0IDwtIHQod2VpZ2h0cykgJSolIHNpZ21hX21hdHJpeCAlKiUgd2VpZ2h0cw0KICAgIA0KICAgIHNpZ19wb3J0IDwtIHNpZzJfcG9ydCAlPiUgYXMubnVtZXJpYygpICU+JSBzcXJ0KCkNCiAgICANCiAgICAjIFByaW50IHJlc3VsdHM6IA0KICAgIA0KICAgIHRpYmJsZShjb21wb3NpdGlvbnMgPSBzdHJfZmxhdHRlbihuYW1lcyhtdSksIGNvbGxhcHNlID0gIl8iKSwgDQogICAgICAgICAgIHdlaWdodCA9IHdlaWdodHMsIA0KICAgICAgICAgICByZXR1cm4gPSBtdV9wb3J0LCANCiAgICAgICAgICAgcmlzayA9IHNpZ19wb3J0LCANCiAgICAgICAgICAgcl9zID0gcmV0dXJuIC8gcmlzaywgDQogICAgICAgICAgIG1hcmtldF9kYXRlID0gbl9uZXh0X21hcmtldF9kYXkpIC0+IGRmX3Jlc3VsdHMNCiAgICANCiAgICByZXR1cm4oZGZfcmVzdWx0cykNCiAgICANCiAgfQ0KICANCiAgDQogICMgQ2hlY2sgdGhlIGZ1bmN0aW9uOiANCiAgDQogIA0KICBsYXBwbHkoMTAwOjI1MCwgcmlza19yZXR1cm5fdG9wNV9wZXJpcGhlcmFsX3BvcnRmb2xpbykgLT4gcGVyX3BvcnRmb2xpb19saXN0DQogIA0KICBkby5jYWxsKCJiaW5kX3Jvd3MiLCBwZXJfcG9ydGZvbGlvX2xpc3QpIC0+IHBlcl9wb3J0Zm9saW8gDQogIA0KICANCiAgIyBGdW50aW9uIGNhbGN1bGF0ZXMgcmlzayBhbmQgcmV0dXJuIGZvciBjZW50cmFsIHBvcnRmb2xpbzogDQogIA0KICByaXNrX3JldHVybl90b3A1X2NlbnRyYWxfcG9ydGZvbGlvIDwtIGZ1bmN0aW9uKG5fbmV4dF9tYXJrZXRfZGF5KSB7DQogICAgDQogICAgIyBuX25leHRfbWFya2V0X2RheSA8LSAxMDANCiAgICANCiAgICByZXR1cm5zX3dpZGUgJT4lIA0KICAgICAgc2VsZWN0KGMoImRhdGUiLCB0b3A2X2NlbnRyYWwpKSAlPiUgDQogICAgICBmaWx0ZXIoZGF0ZSA+IGVuZF9kYXRlKSAlPiUgDQogICAgICBzbGljZSgxOm5fbmV4dF9tYXJrZXRfZGF5KSAtPiByZXR1cm5zX3dpZGVfbmV4dA0KICAgIA0KICAgICMgTWVhbiByZXR1cm46IA0KICAgIA0KICAgIG11IDwtIGNvbE1lYW5zKHJldHVybnNfd2lkZV9uZXh0JT4lIHNlbGVjdCgtZGF0ZSksIG5hLnJtID0gVFJVRSkgDQogICAgDQogICAgIyBDb3ZhcmlhbmNlIG1hdHJpeDogDQogICAgDQogICAgc2lnbWFfbWF0cml4IDwtIGNvdihyZXR1cm5zX3dpZGVfbmV4dCAlPiUgc2VsZWN0KC1kYXRlKSwgdXNlID0gImNvbXBsZXRlLm9icyIpDQogICAgDQogICAgIyBBc3NldCB3ZWlnaHRzOiANCiAgICANCiAgICBuX3N0b2NrcyA8LSBsZW5ndGgobXUpDQogICAgDQogICAgd2VpZ2h0cyA8LSByZXAoMSAvIG5fc3RvY2tzLCBuX3N0b2NrcykNCiAgICANCiAgICAjIFBvcnRmb2xpbyByZXR1cm46IA0KICAgIA0KICAgIG11X3BvcnQgPC0gY3Jvc3Nwcm9kKHdlaWdodHMsIG11KSAlPiUgYXMubnVtZXJpYygpDQogICAgDQogICAgIyBQb3J0Zm9saW8gcmlzazogDQogICAgDQogICAgc2lnMl9wb3J0IDwtIHQod2VpZ2h0cykgJSolIHNpZ21hX21hdHJpeCAlKiUgd2VpZ2h0cw0KICAgIA0KICAgIHNpZ19wb3J0IDwtIHNpZzJfcG9ydCAlPiUgYXMubnVtZXJpYygpICU+JSBzcXJ0KCkNCiAgICANCiAgICAjIFByaW50IHJlc3VsdHM6IA0KICAgIA0KICAgIHRpYmJsZShjb21wb3NpdGlvbnMgPSBzdHJfZmxhdHRlbihuYW1lcyhtdSksIGNvbGxhcHNlID0gIl8iKSwgDQogICAgICAgICAgIHdlaWdodCA9IHdlaWdodHMsIA0KICAgICAgICAgICByZXR1cm4gPSBtdV9wb3J0LCANCiAgICAgICAgICAgcmlzayA9IHNpZ19wb3J0LCANCiAgICAgICAgICAgcl9zID0gcmV0dXJuIC8gcmlzaywgDQogICAgICAgICAgIG1hcmtldF9kYXRlID0gbl9uZXh0X21hcmtldF9kYXkpIC0+IGRmX3Jlc3VsdHMNCiAgICANCiAgICByZXR1cm4oZGZfcmVzdWx0cykNCiAgICANCiAgfQ0KICANCiAgDQogIA0KICBsYXBwbHkoMTAwOjI1MCwgcmlza19yZXR1cm5fdG9wNV9jZW50cmFsX3BvcnRmb2xpbykgLT4gY2VuX3BvcnRmb2xpb19saXN0DQogIA0KICBkby5jYWxsKCJiaW5kX3Jvd3MiLCBjZW5fcG9ydGZvbGlvX2xpc3QpIC0+IGNlbl9wb3J0Zm9saW8gDQogIA0KICANCiAgcGVyX3BvcnRmb2xpbyAlPiUgDQogICAgZ3JvdXBfYnkobWFya2V0X2RhdGUpICU+JSANCiAgICBmaWx0ZXIoIWR1cGxpY2F0ZWQocl9zKSkgJT4lIA0KICAgIG11dGF0ZShyX3MgPSBOVUxMKSAlPiUgDQogICAgdW5ncm91cCgpICU+JSANCiAgICBtdXRhdGUoUG9ydGZvbGlvID0gIlBlcmlwaGVyYWwiKSAtPiBkZjENCiAgDQogIGNlbl9wb3J0Zm9saW8gJT4lIA0KICAgIGdyb3VwX2J5KG1hcmtldF9kYXRlKSAlPiUgDQogICAgZmlsdGVyKCFkdXBsaWNhdGVkKHJfcykpICU+JSANCiAgICBtdXRhdGUocl9zID0gTlVMTCkgJT4lIA0KICAgIHVuZ3JvdXAoKSAlPiUgDQogICAgbXV0YXRlKFBvcnRmb2xpbyA9ICJDZW50cmFsIikgLT4gZGYyDQogIA0KICBiaW5kX3Jvd3MoZGYxLCBkZjIpIC0+IGRmX3RvdGFsDQogIA0KICByZXR1cm4oZGZfdG90YWwpDQogIA0KfQ0KDQoNCg0KDQpgYGANCg0KU28gc8OhbmggcG9ydGZvbGlvIHBlcmZvcm1hbmNlIGPhu6dhIGhhaSBkYW5oIG3hu6VjIHNhdSBjw6FjIHRo4budaSDEkWnhu4NtIDEwMCwuLiwgMjUwIG5nw6B5IGvhu4MgdOG7qyBuZ8OgeSBkYW5oIG3hu6VjIMSR4bqndSB0xrAgxJHGsOG7o2MgdGhp4bq/dCBs4bqtcCAoRmlndXJlIDMpOiANCg0KYGBge3J9DQpjb21wYXJlX3BlcmZvcm1hbmNlX3RvcDYoKSAtPiBkZl9yZXN1bHRzDQoNCiMgUG9ydGZvbGlvIHBlcmZvcm1hbmNlIGJ5IG1hcmtldCBkYXkgYXMgcHJvcG9zZWQgYnkgUG96emkgKDIwMTMpOiANCg0KZGZfcmVzdWx0cyAlPiUgDQogIGdyb3VwX2J5KFBvcnRmb2xpbykgJT4lIA0KICBtdXRhdGUocl9zID0gcmV0dXJuIC8gcmlzaykgLT4gZGZfcmVzdWx0cw0KDQpkZl9yZXN1bHRzICU+JSANCiAgZ2dwbG90KGFlcyhtYXJrZXRfZGF0ZSwgcl9zLCBjb2xvciA9IFBvcnRmb2xpbykpICsgDQogIGdlb21fbGluZShzaXplID0gMSkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsgDQogIGxhYnMoeCA9ICJEYXlzIGZvbGxvd2luZyB0aGUgaW52ZXN0bWVudCBkYXkiLCANCiAgICAgICB5ID0gIlNpZ25hbC10by1ub2lzZSByYXRpbyIsIA0KICAgICAgIHRpdGxlID0gIkZpZ3VyZSAzOiBQb3J0Zm9saW8gUGVyZm9ybWFuY2UsIG0gPSA2IiwgDQogICAgICAgc3VidGl0bGUgPSAiQXNzZXQgd2VpZ2h0cyBhcmUgdW5pZm9ybSwgVE1GRyBOZXR3b3JrIikNCmBgYA0KDQpU4burIEZpZ3VyZSAzIGPDsyB0aOG6uyB0aOG6pXkgcuG6sW5nIHThuqFpIHBo4bqnbiBs4bubbiBt4buRYyB0aOG7nWkgZ2lhbiDEkcaw4bujYyB4w6l0IChzYXUgbmfDoHkgaGFpIGRhbmggbeG7pWMgxJHhuqd1IHTGsCDEkcaw4bujYyB0aGnhur90IGzhuq1wKSB0aMOsIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBj4bqldSB0aMOgbmggdOG7qyA2IGPhu5UgcGhp4bq/dSB0cnVuZyB0w6JtIG5o4bqldCAoxJHGsOG7nW5nIG3DoHUgxJHhu48pIGPDsyBwZXJmb3JtYW5jZSB0aOG6pXAgaMahbiBzbyB24bubaSDEkcaw4budbmcgbcOgdSB4YW5oIChkYW5oIG3hu6VjIMSR4bqndSB0xrAgY+G6pXUgdGjDoG5oIHThu6sgNiBj4buVIHBoaeG6v3Ugbmdv4bqhaSB2aSBuaOG6pXQpLiBL4bq/dCBxdeG6oyBuw6B5IGzDoCB0xrDGoW5nIHThu7EgduG7m2kgbmjhu69uZyBpbnNpZ2h0cyBj4bunYSBQb3p6aSBldCBhbC4gKDIwMTMpLiBL4bq/dCBsdeG6rW4gbsOgeSBjxaluZyBjw7MgdGjhu4MgxJHGsOG7o2MgcsO6dCByYSB0aGVvIGPDoWNoIGtow6FjIGzDoCBzbyBzw6FuaCBhdmVyYWdlIGPhu6dhIFNoYXJwZSBSYXRpbyBj4bunYSBoYWkgZGFuaCBt4bulYyDEkeG6p3UgdMawIG5oxrAgc2F1OiANCg0KDQpgYGB7cn0NCmRmX3Jlc3VsdHMgJT4lIA0KICBncm91cF9ieShQb3J0Zm9saW8pICU+JSANCiAgc3VtbWFyaXNlKGF2Z19yZXR1cm4gPSBtZWFuKHJldHVybiksIGF2Z19yaXNrID0gbWVhbihyaXNrKSwgYXZnX3NoYXJwZSA9IG1lYW4ocl9zKSwgbl9vYnMgPSBuKCkpICU+JSANCiAga25pdHI6OmthYmxlKGNhcHRpb24gPSAiVGFibGUgMTogUG9ydGZvbGlvIFBlcmZvcm1hbmNlIGJ5IEF2ZXJhZ2UgU2lnbmFsLXRvLW5vaXNlIFJhdGlvIikNCmBgYA0KDQpEYW5oIG3hu6VjIMSR4bqndSB0xrAgY8OhYyBj4buVIHBoaeG6v3Ugbmdv4bqhaSB2aSBjw7MgQXZlcmFnZSBTaWduYWwtdG8tbm9pc2UgUmF0aW8gbMOgIDAuMTkyNDk2MiwgY2FvIGjGoW4gMC4xNTA2ODk5IGPhu6dhIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBjw6FjIGPhu5UgcGhp4bq/dSB0cnVuZyB0w6JtLiANCg0KIyBQTUZHIE5ldHdvcmsgZm9yIFBvcnRmb2xpbyBTZWxlY3Rpb24NCg0KxJDhu4Mga2nhu4NtIHRyYSB4ZW0gY8OhYyBraMOhbSBwaMOhIGPhu6dhIFBvenppIGV0IGFsLiAoMjAxMykgY8OzIGPDsm4gxJHDum5nIGtow7RuZyB24bubaSBk4buvIGxp4buHdSBj4bunYSBjw6FjIGPhu5UgcGhp4bq/dSBBTUVYIHRyb25nIGtob+G6o25nIHRo4budaSBnaWFuIHThu6sgMjAxOC0wMS0wMSDEkeG6v24gMjAyMS0xMC0yMCB0csaw4bubYyBo4bq/dCBz4butIGThu6VuZyBow6BtIFtQTUZHXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvTmV0d29ya1Rvb2xib3gvdmVyc2lvbnMvMS4xLjEvdG9waWNzL1BNRkcpIMSRxrDhu6NjIHZp4bq/dCBi4bufaSBbQWxleCBDaHJpc3RlbnNlbl0oaHR0cHM6Ly9zY2hvbGFyLmdvb2dsZS5jb20vY2l0YXRpb25zP3VzZXI9UmJhdHpuUUFBQUFKJmhsPWVuKTogDQoNCmBgYHtyfQ0KIz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCiMgICAgICAgUE1GRyBOZXR3b3JrDQojPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KDQojIFBNRkcgZnVuY3Rpb24gKGFkYXB0ZWQgZnJvbSBBbGV4IENocmlzdGVuc2VuKTogDQoNClBNRkcgPC0gZnVuY3Rpb24oZGF0YSwgYmluYXJ5ID0gRkFMU0UsIHdlaWdodGVkID0gVFJVRSwgbmEuZGF0YSA9IGMoImxpc3R3aXNlIiwgImZpbWwiKSwgcHJvZ0JhciA9IFRSVUUpIHsNCiAgDQogIGNvbF9uYW1lcyA8LSBuYW1lcyhkYXRhKQ0KICANCiAgaWYoISJSQkdMIiAlaW4lIHJvd25hbWVzKGluc3RhbGxlZC5wYWNrYWdlcygpKSkgew0KICAgIGNhdCgiSW4gb3JkZXIgdG8gcGVyZm9ybSB0aGlzIGZ1bmN0aW9uLCBwbGVhc2UgY29weSBjb2RlIGJlbG93IHRvIGluc3RhbGw6IFJCR0wgYW5kIGdyYXBoIHBhY2thZ2VzIiwgc2VwID0gIlxuIikNCiAgICBjYXQoJ3NvdXJjZSgiaHR0cHM6Ly9iaW9jb25kdWN0b3Iub3JnL2Jpb2NMaXRlLlIiKScsIHNlcD0gIlxuIikNCiAgICBjYXQoJ2Jpb2NMaXRlKCJSQkdMIiknLCBzZXAgPSAiXG4iKQ0KICB9DQogIA0KICAjIE1pc3NpbmcgZGF0YSBoYW5kbGluZzogDQogIA0KICBpZihtaXNzaW5nKG5hLmRhdGEpKSB7DQogICAgDQogICAgaWYoYW55KGlzLm5hKGRhdGEpKSkNCiAgICAgIA0KICAgIHtzdG9wKCJNaXNzaW5nIHZhbHVlcyB3ZXJlIGRldGVjdGVkISBTZXQgJ25hLmRhdGEnIGFyZ3VtZW50IikNCiAgICAgIA0KICAgIH1lbHNle25hLmRhdGE8LSJub25lIn0NCiAgICANCiAgfSBlbHNlIHtuYS5kYXRhIDwtIG1hdGNoLmFyZyhuYS5kYXRhKX0NCiAgDQogIGlmKG5hLmRhdGEgPT0gImxpc3R3aXNlIikNCiAgew0KICAgIHJlbSA8LSBuYS5hY3Rpb24obmEub21pdChkYXRhKSkNCiAgICANCiAgICB3YXJuaW5nKHBhc3RlKGxlbmd0aChuYS5hY3Rpb24obmEub21pdChkYXRhKSkpKSwNCiAgICAgICAgICAgICJyb3dzIHdlcmUgcmVtb3ZlZCBmb3IgbWlzc2luZyBkYXRhXG5yb3cocyk6ICIsDQogICAgICAgICAgICBwYXN0ZShuYS5hY3Rpb24obmEub21pdChkYXRhKSksIGNvbGxhcHNlID0gIiwgIikpDQogICAgZGF0YSA8LSBuYS5vbWl0KGRhdGEpDQogIH0gZWxzZSBpZiAobmEuZGF0YSA9PSAiZmltbCIpDQogIHtkYXRhIDwtIHBzeWNoOjpjb3JGaW1sKGRhdGEpfQ0KICANCiAgIyBDb3JybGF0aW9uIG1hdHJpeDogDQogIA0KICBpZihucm93KGRhdGEpID09IG5jb2woZGF0YSkpIHtjb3JtYXQgPC0gZGF0YQ0KICB9IGVsc2UgaWYgKGJpbmFyeSkge2Nvcm1hdCA8LSBwc3ljaDo6dGV0cmFjaG9yaWMoZGF0YSkkcmhvDQogIH0gZWxzZSB7Y29ybWF0IDwtIGNvcihkYXRhKX0NCiAgDQogICMgQ3JlYXRlIHNwYXJzZSBkYXRhOiANCiAgDQogIGkgPC0gYXMudmVjdG9yKHJlcCgxOm5jb2woZGF0YSksIG5jb2woZGF0YSkpKQ0KICBqIDwtIHNvcnQoYXMudmVjdG9yKHJlcCgxOm5jb2woZGF0YSksIG5jb2woZGF0YSkpKSkNCiAgdyA8LSBhcy52ZWN0b3IoY29ybWF0KQ0KICBrayA8LSB3aGljaChpIDwgaikNCiAgDQogIGlqdyA8LSBjYmluZChpW2trXSwgaltra10sIHdba2tdKQ0KICANCiAgaWp3IDwtIGlqd1tvcmRlcihpandbLCAzXSwgZGVjcmVhc2luZyA9IFRSVUUpLCBdDQogIA0KICBQIDwtIE1hdHJpeDo6TWF0cml4KDAsIG5yb3cgPSBuY29sKGRhdGEpLCBuY29sID0gbmNvbChkYXRhKSkNCiAgDQogIGFzX2dyYXBobmVsIDwtIGZ1bmN0aW9uKGdyYXBoKSB7DQogICAgDQogICAgaWYgKCFpZ3JhcGg6OmlzX2lncmFwaChncmFwaCkpIHsNCiAgICAgIHN0b3AoIk5vdCBhbiBpZ3JhcGggZ3JhcGgiKQ0KICAgIH0NCiAgICANCiAgICBpZiAoIm5hbWUiICVpbiUgc3VwcHJlc3NXYXJuaW5ncyhpZ3JhcGg6OnZlcnRleF9hdHRyX25hbWVzKGdyYXBoKSkgJiYNCiAgICAgICAgaXMuY2hhcmFjdGVyKHN1cHByZXNzV2FybmluZ3MoaWdyYXBoOjpWKGdyYXBoKSRuYW1lKSkpIHsNCiAgICAgIG5hbWUgPC0gc3VwcHJlc3NXYXJuaW5ncyhpZ3JhcGg6OlYoZ3JhcGgpJG5hbWUpDQogICAgfSBlbHNlIHsNCiAgICAgIG5hbWUgPC0gYXMuY2hhcmFjdGVyKHNlcShpZ3JhcGg6OnZjb3VudChncmFwaCkpKSAgICANCiAgICB9DQogICAgDQogICAgZWRnZW1vZGUgPC0gInVuZGlyZWN0ZWQiICANCiAgICANCiAgICBpZiAoIndlaWdodCIgJWluJSBpZ3JhcGg6OmVkZ2VfYXR0cl9uYW1lcyhncmFwaCkgJiYNCiAgICAgICAgaXMubnVtZXJpYyhpZ3JhcGg6OkUoZ3JhcGgpJHdlaWdodCkpIHsNCiAgICAgIGFsIDwtIGxhcHBseShpZ3JhcGg6OmFzX2Fkal9lZGdlX2xpc3QoZ3JhcGgsICJvdXQiKSwgYXMudmVjdG9yKQ0KICAgICAgZm9yIChpIGluIHNlcShhbG9uZyA9IGFsKSkgew0KICAgICAgICBlZGdlcyA8LSBpZ3JhcGg6OmVuZHMoZ3JhcGgsIGFsW1tpXV0sIG5hbWVzID0gRkFMU0UpDQogICAgICAgIGVkZ2VzIDwtIGlmZWxzZShlZGdlc1ssIDJdID09IGksIGVkZ2VzWywgMV0sIGVkZ2VzWywgMl0pDQogICAgICAgIHdlaWdodHMgPC0gaWdyYXBoOjpFKGdyYXBoKSR3ZWlnaHRbYWxbW2ldXV0NCiAgICAgICAgYWxbW2ldXSA8LSBsaXN0KGVkZ2VzID0gZWRnZXMsIHdlaWdodHMgPSB3ZWlnaHRzKQ0KICAgICAgfQ0KICAgIH0gZWxzZSB7DQogICAgICBhbCA8LSBpZ3JhcGg6OmFzX2Fkal9saXN0KGdyYXBoLCAib3V0IikNCiAgICAgIGFsIDwtIGxhcHBseShhbCwgZnVuY3Rpb24oeCkgbGlzdChlZGdlcyA9IGFzLnZlY3Rvcih4KSkpDQogICAgfSAgDQogICAgDQogICAgbmFtZXMoYWwpIDwtIG5hbWUNCiAgICByZXMgPC0gZ3JhcGg6OmdyYXBoTkVMKG5vZGVzID0gbmFtZSwgZWRnZUwgPSBhbCwgZWRnZW1vZGUgPSBlZGdlbW9kZSkNCiAgICANCiAgICAjIEFkZCBncmFwaCBhdHRyaWJ1dGVzIChvdGhlciB0aGFuICdkaXJlY3RlZCcpDQogICAgIyBBcmUgdGhpcyAib2ZmaWNpYWxseSIgc3VwcG9ydGVkIGF0IGFsbD8NCiAgICANCiAgICBnLm4gPC0gaWdyYXBoOjpncmFwaF9hdHRyX25hbWVzKGdyYXBoKQ0KICAgIGlmICgiZGlyZWN0ZWQiICVpbiUgZy5uKSB7DQogICAgICB3YXJuaW5nKCJDYW5ub3QgYWRkIGdyYXBoIGF0dHJpYnV0ZSBgZGlyZWN0ZWQnIikNCiAgICAgIGcubiA8LSBnLm5bZy5uICE9ICJkaXJlY3RlZCIgXQ0KICAgIH0NCiAgICBmb3IgKG4gaW4gZy5uKSB7DQogICAgICByZXNAZ3JhcGhEYXRhW1tuXV0gPC0gaWdyYXBoOjpncmFwaF9hdHRyKGdyYXBoLCBuKQ0KICAgIH0NCiAgICANCiAgICAjIyBBZGQgdmVydGV4IGF0dHJpYnV0ZXMgKG90aGVyIHRoYW4gJ25hbWUnLCB0aGF0IGlzIGFscmVhZHkgYWRkZWQgYXMgdmVydGV4IG5hbWVzKTogDQogICAgDQogICAgdi5uIDwtIGlncmFwaDo6dmVydGV4X2F0dHJfbmFtZXMoZ3JhcGgpDQogICAgdi5uIDwtIHYublt2Lm4gIT0gIm5hbWUiXQ0KICAgIGZvciAobiBpbiB2Lm4pIHsNCiAgICAgIGdyYXBoOjpub2RlRGF0YURlZmF1bHRzKHJlcywgYXR0ciA9IG4pIDwtIE5BDQogICAgICBncmFwaDo6bm9kZURhdGEocmVzLCBhdHRyID0gbikgPC0gaWdyYXBoOjp2ZXJ0ZXhfYXR0cihncmFwaCwgbikNCiAgICB9DQogICAgDQogICAgIyBBZGQgZWRnZSBhdHRyaWJ1dGVzIChvdGhlciB0aGFuICd3ZWlnaHQnKTogDQogICAgDQogICAgZS5uIDwtIGlncmFwaDo6ZWRnZV9hdHRyX25hbWVzKGdyYXBoKQ0KICAgIGUubiA8LSBlLm5bZS5uICE9ICJ3ZWlnaHQiXQ0KICAgIGlmIChsZW5ndGgoZS5uKSA+IDApIHsNCiAgICAgIGVsIDwtIGlncmFwaDo6YXNfZWRnZWxpc3QoZ3JhcGgpDQogICAgICBlbCA8LSBwYXN0ZShzZXAgPSAifCIsIGVsWywgMV0sIGVsWywgMl0pDQogICAgICBmb3IgKG4gaW4gZS5uKSB7DQogICAgICAgIGdyYXBoOjplZGdlRGF0YURlZmF1bHRzKHJlcywgYXR0ciA9IG4pIDwtIE5BDQogICAgICAgIHJlc0BlZGdlRGF0YUBkYXRhW2VsXSA8LSBtYXBwbHkoZnVuY3Rpb24oeCwgeSkgew0KICAgICAgICAgIHh4IDwtIGMoeCwgeSk7IG5hbWVzKHh4KVtsZW5ndGgoeHgpXSA8LSBuOyB4eH0sDQogICAgICAgICAgcmVzQGVkZ2VEYXRhQGRhdGFbZWxdLA0KICAgICAgICAgIGlncmFwaDo6ZWRnZV9hdHRyKGdyYXBoLCBuKSwNCiAgICAgICAgICBTSU1QTElGWSA9IEZBTFNFKQ0KICAgICAgfQ0KICAgIH0NCiAgICANCiAgICByZXMNCiAgfQ0KICANCiAgZm9yKGlpIGluIDE6cG1pbig2LCBucm93KGlqdykpKQ0KICB7DQogICAgUFtpandbaWksIDFdLCBpandbaWksIDJdXSA8LSBpandbaWksIDNdDQogICAgUFtpandbaWksIDJdLCBpandbaWksIDFdXSA8LSBpandbaWksIDNdDQogIH0NCiAgDQogIEUgPC0gNg0KICBQMSA8LSBQDQogIA0KICBpZihwcm9nQmFyID09IFRSVUUpDQogIHtwYiA8LSB0eHRQcm9ncmVzc0JhcihtYXggPSAoMyoobmNvbChkYXRhKSAtIDIpKSwgc3R5bGUgPSAzKX0NCiAgDQogIHdoaWxlKEUgPCAzKihuY29sKGRhdGEpIC0gMikpDQogIHsNCiAgICBpaSA8LSBpaSArIDENCiAgICBQMVtpandbaWksIDFdLCBpandbaWksIDJdXSA8LSBpandbaWksIDNdDQogICAgUDFbaWp3W2lpLCAyXSwgaWp3W2lpLCAxXV0gPC0gaWp3W2lpLCAzXQ0KICAgIA0KICAgIGdyYXBoIDwtIGlncmFwaDo6YXMuaWdyYXBoKHFncmFwaDo6cWdyYXBoKFAxLCBEb05vdFBsb3QgPSBUUlVFKSkNCiAgICANCiAgICBnPC1hc19ncmFwaG5lbChncmFwaCkNCiAgICANCiAgICBpZihSQkdMOjpib3llck15cnZvbGRQbGFuYXJpdHlUZXN0KGcpID09IFRSVUUpDQogICAgew0KICAgICAgUCA8LSBQMQ0KICAgICAgRSA8LSBFICsgMQ0KICAgICAgDQogICAgICBpZihwcm9nQmFyID09IFRSVUUpDQogICAgICB7c2V0VHh0UHJvZ3Jlc3NCYXIocGIsIEUpfQ0KICAgIH0gZWxzZSB7UDEgPC0gUH0NCiAgICANCiAgICBpZihpaSA+IChuY29sKGRhdGEpKihuY29sKGRhdGEpIC0gMSkgLyAyKSkNCiAgICB7bWVzc2FnZSgiUE1GRyBub3QgZm91bmQiKX0NCiAgICANCiAgfQ0KICBpZihwcm9nQmFyID09IFRSVUUpDQogIHtjbG9zZShwYil9DQogIA0KICBwbWZnIDwtIGFzLm1hdHJpeChQKQ0KICANCiAgaWYoIXdlaWdodGVkKQ0KICAgIA0KICB7cG1mZyA8LSBpZmVsc2UocG1mZyAhPSAwLCAxLCAwKX0NCiAgDQogIGNvbG5hbWVzKHBtZmcpIDwtIGNvbF9uYW1lcw0KICANCiAgcm93Lm5hbWVzKHBtZmcpIDwtIGNvbF9uYW1lcw0KICANCiAgcmV0dXJuKHBtZmcpDQp9DQpgYGANCg0KU+G7rSBk4bulbmcgaMOgbSBuw6B5IMSR4buDIHTDrW5oIEhDIG1lYXN1cmU6IA0KDQpgYGB7cn0NCiMgQ29uc3RydWN0IFBNRkcgbmV0d29yazogDQoNClBNRkcocmV0dXJuX3dpZGVfbWluaV8yNTAsIHByb2dCYXIgPSBGQUxTRSkgLT4gcG1mZw0KDQojIENhbGN1bGF0ZSBIQyBtZWFzdXJlOiANCg0KaHlicmlkKHBtZmcpIC0+IGhjX21lYXN1cmVfcG1mZw0KYGBgDQoNCkPDsyB0aOG7gyB0aOG6pXkgaGFpIGPDoWNoIHRp4bq/cCBj4bqtbiBz4bq9IHThuqFvIHJhIG5o4buvbmcga+G6v3QgcXXhuqMgdMawxqFuZyDEkeG7kWkga2jDoWMgYmnhu4d0IHbhu4EgSEM6IA0KDQpgYGB7cn0NCiMgSEMgYnkgVE1GRyBhcHByb2FjaDogDQpoY19tZWFzdXJlICU+JSBoZWFkKCkNCg0KIyBIQyBieSBQTUZHIGFwcHJvYWNoOiANCmhjX21lYXN1cmVfcG1mZyAlPiUgaGVhZCgpDQpgYGANCg0KTGlzdCByYSA2IGPhu5UgcGhp4bq/dSB0cnVuZyB0w6JtIG5o4bqldCAtIG5nb+G6oWkgdmkgbmjhuqV0IHRoZW8gUE1GRyBOZXR3b3JrOiANCg0KYGBge3J9DQpkYXRhLmZyYW1lKHN5bWJvbCA9IG5hbWVzKGhjX21lYXN1cmVfcG1mZyksIGhjX21lYXN1cmUgPSBoY19tZWFzdXJlX3BtZmcpIC0+IGNlbnRyYWxfcGVyX3BtZmcNCg0KY2VudHJhbF9wZXJfcG1mZyAlPiUgDQogIHRvcF9uKG4gPSA2LCB3dCA9IGhjX21lYXN1cmUpICU+JSANCiAgc2xpY2UoMTo2KSAlPiUgDQogIHB1bGwoc3ltYm9sKSAtPiB0b3A2X3BlcmlwaGVyYWxfcG1mZw0KDQpjZW50cmFsX3Blcl9wbWZnICU+JSANCiAgdG9wX24obiA9IDYsIHd0ID0gLWhjX21lYXN1cmUpICU+JSANCiAgc2xpY2UoMTo2KSAlPiUgDQogIHB1bGwoc3ltYm9sKSAtPiB0b3A2X2NlbnRyYWxfcG1mZw0KYGBgDQoNCkPDsyB0aOG7gyB0aOG6pXkgNiBj4buVIHBoaeG6v3UgdHJ1bmcgdMOibSBuaOG6pXQgdOG7qyBoYWkgY8OhY2ggdGnhur9wIGPhuq1uIG7DoHkgbMOgIGtow6FjIG5oYXU6IA0KDQpgYGB7cn0NCiMgQ29tcGFyZTogDQp0b3A2X2NlbnRyYWwNCg0KdG9wNl9jZW50cmFsX3BtZmcNCmBgYA0KDQpOaMawbmcgbmjDs20gNiBj4buVIHBoaeG6v3Ugbmdv4bqhaSB2aSBs4bqhaSBraMOhIGdp4buRbmcgbmhhdTogDQoNCmBgYHtyfQ0KdG9wNl9wZXJpcGhlcmFsDQoNCnRvcDZfcGVyaXBoZXJhbF9wbWZnDQpgYGANCg0KU28gc8OhbmggcG9ydGZvbGlvIHBlcmZvcm1hbmNlIGPhu6dhIGhhaSBraeG7g3UgZGFuaCBt4bulYyDEkeG6p3UgdMawIHThu6sgUE1GRyBOZXR3b3JrIChGaWd1cmUgNCk6IA0KDQoNCmBgYHtyfQ0KY29tcGFyZV9wZXJmb3JtYW5jZV90b3A2X1BNRkcgPC0gZnVuY3Rpb24oLi4uKSB7DQogIA0KICAjPT09PT09PT09PT09PT09PT09PT09PT09PQ0KICAjICBQb3J0Zm9saW8gUGVyZm9ybWFuY2UNCiAgIz09PT09PT09PT09PT09PT09PT09PT09PT0NCiAgDQogIA0KICAjIEZ1bnRpb24gY2FsY3VsYXRlcyByaXNrIGFuZCByZXR1cm4gZm9yIHBlcmlwaGVyYWwgcG9ydGZvbGlvOiANCiAgDQogIHJpc2tfcmV0dXJuX3RvcDVfcGVyaXBoZXJhbF9wb3J0Zm9saW8gPC0gZnVuY3Rpb24obl9uZXh0X21hcmtldF9kYXkpIHsNCiAgICANCiAgICAjIG5fbmV4dF9tYXJrZXRfZGF5IDwtIDEwMA0KICAgIA0KICAgIHJldHVybnNfd2lkZSAlPiUgDQogICAgICBzZWxlY3QoYygiZGF0ZSIsIHRvcDZfcGVyaXBoZXJhbF9wbWZnKSkgJT4lIA0KICAgICAgZmlsdGVyKGRhdGUgPiBlbmRfZGF0ZSkgJT4lIA0KICAgICAgc2xpY2UoMTpuX25leHRfbWFya2V0X2RheSkgLT4gcmV0dXJuc193aWRlX25leHQNCiAgICANCiAgICAjIE1lYW4gcmV0dXJuOiANCiAgICANCiAgICBtdSA8LSBjb2xNZWFucyhyZXR1cm5zX3dpZGVfbmV4dCU+JSBzZWxlY3QoLWRhdGUpLCBuYS5ybSA9IFRSVUUpIA0KICAgIA0KICAgICMgQ292YXJpYW5jZSBtYXRyaXg6IA0KICAgIA0KICAgIHNpZ21hX21hdHJpeCA8LSBjb3YocmV0dXJuc193aWRlX25leHQgJT4lIHNlbGVjdCgtZGF0ZSksIHVzZSA9ICJjb21wbGV0ZS5vYnMiKQ0KICAgIA0KICAgICMgQXNzZXQgd2VpZ2h0czogDQogICAgDQogICAgbl9zdG9ja3MgPC0gbGVuZ3RoKG11KQ0KICAgIA0KICAgIHdlaWdodHMgPC0gcmVwKDEgLyBuX3N0b2Nrcywgbl9zdG9ja3MpDQogICAgDQogICAgIyBQb3J0Zm9saW8gcmV0dXJuOiANCiAgICANCiAgICBtdV9wb3J0IDwtIGNyb3NzcHJvZCh3ZWlnaHRzLCBtdSkgJT4lIGFzLm51bWVyaWMoKQ0KICAgIA0KICAgICMgUG9ydGZvbGlvIHJpc2s6IA0KICAgIA0KICAgIHNpZzJfcG9ydCA8LSB0KHdlaWdodHMpICUqJSBzaWdtYV9tYXRyaXggJSolIHdlaWdodHMNCiAgICANCiAgICBzaWdfcG9ydCA8LSBzaWcyX3BvcnQgJT4lIGFzLm51bWVyaWMoKSAlPiUgc3FydCgpDQogICAgDQogICAgIyBQcmludCByZXN1bHRzOiANCiAgICANCiAgICB0aWJibGUoY29tcG9zaXRpb25zID0gc3RyX2ZsYXR0ZW4obmFtZXMobXUpLCBjb2xsYXBzZSA9ICJfIiksIA0KICAgICAgICAgICB3ZWlnaHQgPSB3ZWlnaHRzLCANCiAgICAgICAgICAgcmV0dXJuID0gbXVfcG9ydCwgDQogICAgICAgICAgIHJpc2sgPSBzaWdfcG9ydCwgDQogICAgICAgICAgIHJfcyA9IHJldHVybiAvIHJpc2ssIA0KICAgICAgICAgICBtYXJrZXRfZGF0ZSA9IG5fbmV4dF9tYXJrZXRfZGF5KSAtPiBkZl9yZXN1bHRzDQogICAgDQogICAgcmV0dXJuKGRmX3Jlc3VsdHMpDQogICAgDQogIH0NCiAgDQogIA0KICAjIENoZWNrIHRoZSBmdW5jdGlvbjogDQogIA0KICANCiAgbGFwcGx5KDEwMDoyNTAsIHJpc2tfcmV0dXJuX3RvcDVfcGVyaXBoZXJhbF9wb3J0Zm9saW8pIC0+IHBlcl9wb3J0Zm9saW9fbGlzdA0KICANCiAgZG8uY2FsbCgiYmluZF9yb3dzIiwgcGVyX3BvcnRmb2xpb19saXN0KSAtPiBwZXJfcG9ydGZvbGlvIA0KICANCiAgDQogICMgRnVudGlvbiBjYWxjdWxhdGVzIHJpc2sgYW5kIHJldHVybiBmb3IgY2VudHJhbCBwb3J0Zm9saW86IA0KICANCiAgcmlza19yZXR1cm5fdG9wNV9jZW50cmFsX3BvcnRmb2xpbyA8LSBmdW5jdGlvbihuX25leHRfbWFya2V0X2RheSkgew0KICAgIA0KICAgICMgbl9uZXh0X21hcmtldF9kYXkgPC0gMTAwDQogICAgDQogICAgcmV0dXJuc193aWRlICU+JSANCiAgICAgIHNlbGVjdChjKCJkYXRlIiwgdG9wNl9jZW50cmFsX3BtZmcpKSAlPiUgDQogICAgICBmaWx0ZXIoZGF0ZSA+IGVuZF9kYXRlKSAlPiUgDQogICAgICBzbGljZSgxOm5fbmV4dF9tYXJrZXRfZGF5KSAtPiByZXR1cm5zX3dpZGVfbmV4dA0KICAgIA0KICAgICMgTWVhbiByZXR1cm46IA0KICAgIA0KICAgIG11IDwtIGNvbE1lYW5zKHJldHVybnNfd2lkZV9uZXh0JT4lIHNlbGVjdCgtZGF0ZSksIG5hLnJtID0gVFJVRSkgDQogICAgDQogICAgIyBDb3ZhcmlhbmNlIG1hdHJpeDogDQogICAgDQogICAgc2lnbWFfbWF0cml4IDwtIGNvdihyZXR1cm5zX3dpZGVfbmV4dCAlPiUgc2VsZWN0KC1kYXRlKSwgdXNlID0gImNvbXBsZXRlLm9icyIpDQogICAgDQogICAgIyBBc3NldCB3ZWlnaHRzOiANCiAgICANCiAgICBuX3N0b2NrcyA8LSBsZW5ndGgobXUpDQogICAgDQogICAgd2VpZ2h0cyA8LSByZXAoMSAvIG5fc3RvY2tzLCBuX3N0b2NrcykNCiAgICANCiAgICAjIFBvcnRmb2xpbyByZXR1cm46IA0KICAgIA0KICAgIG11X3BvcnQgPC0gY3Jvc3Nwcm9kKHdlaWdodHMsIG11KSAlPiUgYXMubnVtZXJpYygpDQogICAgDQogICAgIyBQb3J0Zm9saW8gcmlzazogDQogICAgDQogICAgc2lnMl9wb3J0IDwtIHQod2VpZ2h0cykgJSolIHNpZ21hX21hdHJpeCAlKiUgd2VpZ2h0cw0KICAgIA0KICAgIHNpZ19wb3J0IDwtIHNpZzJfcG9ydCAlPiUgYXMubnVtZXJpYygpICU+JSBzcXJ0KCkNCiAgICANCiAgICAjIFByaW50IHJlc3VsdHM6IA0KICAgIA0KICAgIHRpYmJsZShjb21wb3NpdGlvbnMgPSBzdHJfZmxhdHRlbihuYW1lcyhtdSksIGNvbGxhcHNlID0gIl8iKSwgDQogICAgICAgICAgIHdlaWdodCA9IHdlaWdodHMsIA0KICAgICAgICAgICByZXR1cm4gPSBtdV9wb3J0LCANCiAgICAgICAgICAgcmlzayA9IHNpZ19wb3J0LCANCiAgICAgICAgICAgcl9zID0gcmV0dXJuIC8gcmlzaywgDQogICAgICAgICAgIG1hcmtldF9kYXRlID0gbl9uZXh0X21hcmtldF9kYXkpIC0+IGRmX3Jlc3VsdHMNCiAgICANCiAgICByZXR1cm4oZGZfcmVzdWx0cykNCiAgICANCiAgfQ0KICANCiAgDQogIA0KICBsYXBwbHkoMTAwOjI1MCwgcmlza19yZXR1cm5fdG9wNV9jZW50cmFsX3BvcnRmb2xpbykgLT4gY2VuX3BvcnRmb2xpb19saXN0DQogIA0KICBkby5jYWxsKCJiaW5kX3Jvd3MiLCBjZW5fcG9ydGZvbGlvX2xpc3QpIC0+IGNlbl9wb3J0Zm9saW8gDQogIA0KICANCiAgcGVyX3BvcnRmb2xpbyAlPiUgDQogICAgZ3JvdXBfYnkobWFya2V0X2RhdGUpICU+JSANCiAgICBmaWx0ZXIoIWR1cGxpY2F0ZWQocl9zKSkgJT4lIA0KICAgIG11dGF0ZShyX3MgPSBOVUxMKSAlPiUgDQogICAgdW5ncm91cCgpICU+JSANCiAgICBtdXRhdGUoUG9ydGZvbGlvID0gIlBlcmlwaGVyYWwiKSAtPiBkZjENCiAgDQogIGNlbl9wb3J0Zm9saW8gJT4lIA0KICAgIGdyb3VwX2J5KG1hcmtldF9kYXRlKSAlPiUgDQogICAgZmlsdGVyKCFkdXBsaWNhdGVkKHJfcykpICU+JSANCiAgICBtdXRhdGUocl9zID0gTlVMTCkgJT4lIA0KICAgIHVuZ3JvdXAoKSAlPiUgDQogICAgbXV0YXRlKFBvcnRmb2xpbyA9ICJDZW50cmFsIikgLT4gZGYyDQogIA0KICBiaW5kX3Jvd3MoZGYxLCBkZjIpIC0+IGRmX3RvdGFsDQogIA0KICByZXR1cm4oZGZfdG90YWwpDQogIA0KfQ0KDQpjb21wYXJlX3BlcmZvcm1hbmNlX3RvcDZfUE1GRygpIC0+IGRmX3Jlc3VsdHNfUE1GRw0KDQpkZl9yZXN1bHRzX1BNRkcgJT4lIA0KICBncm91cF9ieShQb3J0Zm9saW8pICU+JSANCiAgbXV0YXRlKHJfcyA9IHJldHVybiAvIHJpc2spIC0+IGRmX3Jlc3VsdHNfUE1GRw0KDQpkZl9yZXN1bHRzX1BNRkcgJT4lIA0KICBnZ3Bsb3QoYWVzKG1hcmtldF9kYXRlLCByX3MsIGNvbG9yID0gUG9ydGZvbGlvKSkgKyANCiAgZ2VvbV9saW5lKHNpemUgPSAxKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgKyANCiAgbGFicyh4ID0gIkRheXMgZm9sbG93aW5nIHRoZSBpbnZlc3RtZW50IGRheSIsIA0KICAgICAgIHkgPSAiU2lnbmFsLXRvLW5vaXNlIHJhdGlvIiwgDQogICAgICAgdGl0bGUgPSAiRmlndXJlIDQ6IFBvcnRmb2xpbyBQZXJmb3JtYW5jZSwgbSA9IDYiLCANCiAgICAgICBzdWJ0aXRsZSA9ICJBc3NldCB3ZWlnaHRzIGFyZSB1bmlmb3JtLCBQTUZHIE5ldHdvcmsiKQ0KDQpgYGANCg0KRmlndXJlIDQgY2hvIHRo4bqleSBkYW5oIG3hu6VjIMSR4bqndSB0xrAgbmdv4bqhaSB2aSAoxJHGsOG7nW5nIG3DoHUgeGFuaCkgduG6q24gY8OzIHBlcmZvcm1hbmNlIHThu5F0IGjGoW4uIFTGsMahbmcgdOG7sSBjw6FjIHRpw6p1IGNow60gxJHDoW5oIGdpw6EgcGVyZm9ybWFuY2UgY+G7p2EgaGFpIGRhbmggbeG7pWMgxJHGsOG7o2MgY2hvIOG7nyBUYWJsZSAyIGTGsOG7m2kgxJHDonk6IA0KDQpgYGB7cn0NCmRmX3Jlc3VsdHNfUE1GRyAlPiUgDQogIGdyb3VwX2J5KFBvcnRmb2xpbykgJT4lIA0KICBzdW1tYXJpc2UoYXZnX3JldHVybiA9IG1lYW4ocmV0dXJuKSwgYXZnX3Jpc2sgPSBtZWFuKHJpc2spLCBhdmdfc2hhcnBlID0gbWVhbihyX3MpLCBuX29icyA9IG4oKSkgJT4lIA0KICBrbml0cjo6a2FibGUoY2FwdGlvbiA9ICJUYWJsZSAyOiBQb3J0Zm9saW8gUGVyZm9ybWFuY2UgYnkgQXZlcmFnZSBTaWduYWwtdG8tbm9pc2UgUmF0aW8iKQ0KYGBgDQoNCg0KIyBDb25jbHVzaW9uDQoNClThu6sga+G6v3QgcXXhuqMgdGjhu7FjIG5naGnhu4dtIHbhu5tpIGLhu5kgZOG7ryBsaeG7h3UgMTAwIGPhu5UgcGhp4bq/dSBBTUVYIGPDsyB24buRbiBow7NhIHRo4buLIHRyxrDhu51uZyBs4bubbiBuaOG6pXQgY8OzIHRo4buDIHLDunQgcmEgdsOgaSBr4bq/dCBsdeG6rW4gcXVhbiB0cuG7jW5nIHNhdTogDQoNCi0gQ8OhYyBraMOhbSBwaMOhIGNow61uaCBj4bunYSBQb3p6aSBldCBhbC4gKDIwMTMpIHbhuqtuIGzhurdwIGzhuqFpIHbhu5tpIGThu68gbGnhu4d1IGPhuq1wIG5o4bqtdCBoxqFuLiBD4bulIHRo4buDLCBwZXJmb3JtYW5jZSBj4bunYSBkYW5oIG3hu6VjIMSR4bqndSB0xrAgY+G6pXUgdGjDoG5oIHThu6sgY8OhYyBj4buVIHBoaeG6v3Ugbmdv4bqhaSB2aSBuaOG6pXQgduG6q24gdOG7kXQgaMahbiBwZXJmb3JtYW5jZSBj4bunYSBkYW5oIG3hu6VjIMSR4bqndSB0xrAgY+G6pXUgdGjDoG5oIHThu6sgY8OhYyBj4buVIHBoaeG6v3UgdHJ1bmcgdMOibSBuaOG6pXQgYuG6pXQga+G7gyBjw6FjaCB0aeG6v3AgY+G6rW4gbMOgIFRNRkcgaGF5IFBNRkcuIA0KDQotIEh5YmlyZCBDZW50cmFsaXR5IChIQykgdOG7qyBoYWkgY8OhY2ggdGnhur9wIGPhuq1uIFRNRkcgdsOgIFBNRkcgbMOgIHTGsMahbmcgxJHhu5FpIGtow6FjIGJp4buHdC4gVHV5IG5oacOqbiBj4bqldSB0csO6YyBkYW5oIG3hu6VjIMSR4bqndSB0xrAgbmdv4bqhaSB2aSBs4bqhaSBraMOhIGdp4buRbmcgbmhhdTogZ2nhu5FuZyBuaGF1IDUgdHJvbmcgdOG7lW5nIHPhu5EgNiBj4buVIHBoaeG6v3UuIA0KDQoNCiMgQmlibGlvZ3JhcGh5DQoNCjEuIEYuIFBvenppLCBULiBEaSBNYXR0ZW8sIGFuZCBULiBBc3RlLiBTcHJlYWQgb2YgcmlzayBhY3Jvc3MgZmluYW5jaWFsIG1hcmtldHM6IEJldHRlciB0byBpbnZlc3QgaW4gdGhlIHBlcmlwaGVyaWVzLiBTY2llbnRpZmljIFJlcG9ydHMsIDM6MTY2NSwgMjAxMy4gVVJMIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDM4L3NyZXAwMTY2NS4gW3A0MjhdLiANCg0KMi4gRi4gUG96emkuIEZpbHRlcmluZyBmaW5hbmNpYWwgbmV0d29ya3MgYW5kIG9wdGltYWwgcG9ydGZvbGlvIHNlbGVjdGlvbi4gUGguRC4gVGhlc2lzIChUaGUgQXVzdHJhbGlhbiBOYXRpb25hbCBVbml2ZXJzaXR5LCBDYW5iZXJyYSwgMjAxMykuDQoNCjMuIFQuIERpIE1hdHRlbywgRi4gUG96emksIFQuIEFzdGUuIFRoZSB1c2Ugb2YgZHluYW1pY2FsIG5ldHdvcmtzIHRvIGRldGVjdCB0aGUgaGllcmFyY2hpY2FsIG9yZ2FuaXphdGlvbiBvZiBmaW5hbmNpYWwgbWFya2V0IHNlY3RvcnMuIEV1cm9wZWFuIFBoeXNpY2FsIEpvdXJuYWwgQiA3MywgM+KAkzExICgyMDEwKQ0KDQo0LiBELiBZLiBLZW5ldHQsIE0uIFR1bW1pbmVsbG8sIEEuIE1hZGksIEcuIEd1ci1HZXJzaGdvcmVuLCBSLiBOLiBNYW50ZWduYSwgYW5kIEUuIEJlbi1KYWNvYi4gRG9taW5hdGluZyBjbGFzcCBvZiB0aGUgZmluYW5jaWFsIHNlY3RvciByZXZlYWxlZCBieSBwYXJ0aWFsIGNvcnJlbGF0aW9uIGFuYWx5c2lzIG9mIHRoZSBzdG9jayBtYXJrZXQuIFBsb1Mgb25lLCA1KDEyKTplMTUwMzIsIDIwMTAuIFVSTCBodHRwczovL2RvaS5vcmcvMTAuMTM3MS9qb3VybmFsLnBvbmUuMDAxNTAzMi4gW3A0MjZdLiANCg0KNS4gVy4gQmFyZnVzcywgRy4gUC4gTWFzc2FyYSwgVC4gRGkgTWF0dGVvLCBhbmQgVC4gQXN0ZS4gUGFyc2ltb25pb3VzIG1vZGVsaW5nIHdpdGggaW5mb3JtYXRpb24gZmlsdGVyaW5nIG5ldHdvcmtzLiBQaHlzaWNhbCBSZXZpZXcgRSwgOTQoNik6MDYyMzA2LCAyMDE2LiBVUkwgaHR0cHM6Ly9kb2kub3JnLzEwLjExMDMvUGh5c1JldkUuOTQuIDA2MjMwNi4gW3A0MjMsIDQyNCwgNDI1XS4gDQoNCg0KDQo=