LyoqIEBmaWxlDQogIERlYnVnIEFnZW50IGxpYnJhcnkgaW1wbGVtZW50aXRpb24gd2l0aCBlbXB0eSBmdW5jdGlvbnMuDQoNCiAgQ29weXJpZ2h0IChjKSAyMDEwLCBJbnRlbCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC48QlI+DQogIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMNCiAgYXJlIGxpY2Vuc2VkIGFuZCBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIEJTRCBMaWNlbnNlDQogIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLiAgVGhlIGZ1bGwgdGV4dCBvZiB0aGUgbGljZW5zZSBtYXkgYmUgZm91bmQgYXQNCiAgaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL2JzZC1saWNlbnNlLnBocA0KDQogIFRIRSBQUk9HUkFNIElTIERJU1RSSUJVVEVEIFVOREVSIFRIRSBCU0QgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLA0KICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgUkVQUkVTRU5UQVRJT05TIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELg0KDQoqKi8NCg0KI2luY2x1ZGUgIkdkYkRlYnVnQWdlbnQuaCINCg0KDQpVSU5UTiAgICAgZ01heFByb2Nlc3NvckluZGV4ID0gMDsNCg0KLy8NCi8vIEJ1ZmZlcnMgZm9yIGJhc2ljIGdkYiBjb21tdW5pY2F0aW9uDQovLw0KQ0hBUjggZ0luQnVmZmVyW01BWF9CVUZfU0laRV07DQpDSEFSOCBnT3V0QnVmZmVyW01BWF9CVUZfU0laRV07DQoNCg0KLy8NCi8vIEdsb2JhbHMgZm9yIHJldHVybmluZyBYTUwgZnJvbSBxWGZlcjpsaWJyYXJpZXM6cmVhZCBwYWNrZXQNCi8vDQpVSU5UTiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ1BhY2tldHFYZmVyTGlicmFyeU9mZnNldCA9IDA7DQpVSU5UTiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ0VmaURlYnVnSW1hZ2VUYWJsZUVudHJ5ID0gMDsNCkNIQVI4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnWGZlckxpYnJhcnlCdWZmZXJbMjAwMF07DQoNCkdMT0JBTF9SRU1PVkVfSUZfVU5SRUZFUkVOQ0VEIENPTlNUIENIQVI4IG1IZXhUb1N0cltdID0geycwJywnMScsJzInLCczJywnNCcsJzUnLCc2JywnNycsJzgnLCc5JywnQScsJ0InLCdDJywnRCcsJ0UnLCdGJ307DQoNCg0KLy8gYWRkLXN5bWJvbC1maWxlIGM6L3dvcmsvZWRrMi9CdWlsZC9CZWFnbGVCb2FyZC9ERUJVR19HQ0M0OC9BUk0vQmVhZ2xlQm9hcmRQa2cvU2VjL1NlYy9ERUJVRy9CZWFnbGVCb2FyZFNlYy5kbGwgMHg4MDAwODM2MA0KQ0hBUjggICpxWGZlckhhY2sgPSAiPGxpYnJhcnkgbmFtZT1cImM6L3dvcmsvZWRrMi9CdWlsZC9CZWFnbGVCb2FyZC9ERUJVR19HQ0M0OC9BUk0vQmVhZ2xlQm9hcmRQa2cvU2VjL1NlYy9ERUJVRy9CZWFnbGVCb2FyZFNlYy5kbGxcIj48c2VnbWVudCBhZGRyZXNzPVwiMHg4MDAwODM2MFwiLz48L2xpYnJhcnk+IjsNCg0KVUlOVE4NCmdYZmVyT2JqZWN0UmVhZFJlc3BvbnNlICgNCiAgSU4gIENIQVI4ICAgICAgICAgVHlwZSwNCiAgSU4gIENIQVI4ICAgICAgICAgKlN0cg0KICApDQp7DQogIENIQVI4ICAgKk91dEJ1ZlB0cjsgICAgICAgICAgICAgLy8gcG9pbnRlciB0byB0aGUgb3V0cHV0IGJ1ZmZlcg0KICBDSEFSOCAgIENoYXI7DQogIFVJTlROICAgQ291bnQ7DQoNCiAgLy8gcmVzcG9uY2Ugc3RhcnRzIHdpdGggJ20nIG9yICdsJyBpZiBpdCBpcyB0aGUgZW5kDQogIE91dEJ1ZlB0ciA9IGdPdXRCdWZmZXI7DQogICpPdXRCdWZQdHIrKyA9IFR5cGU7DQogIENvdW50ID0gMTsNCg0KICAvLyBCaW5hcnkgZGF0YSBlbmNvZGluZw0KICBPdXRCdWZQdHIgPSBnT3V0QnVmZmVyOw0KICB3aGlsZSAoKlN0ciAhPSAnXDAnKSB7DQogICAgQ2hhciA9ICpTdHIrKzsNCiAgICBpZiAoKENoYXIgPT0gMHg3ZCkgfHwgKENoYXIgPT0gMHgyMykgfHwgKENoYXIgPT0gMHgyNCkgfHwgKENoYXIgPT0gMHgyYSkpIHsNCiAgICAgIC8vIGVzY2FwZSBjaGFyYWN0ZXINCiAgICAgICpPdXRCdWZQdHIrKyA9IDB4N2Q7DQoNCiAgICAgIENoYXIgXj0gMHgyMDsNCiAgICB9DQogICAgKk91dEJ1ZlB0cisrID0gQ2hhcjsNCiAgICBDb3VudCsrOw0KICB9DQoNCiAgKk91dEJ1ZlB0ciA9ICdcMCcgOyAgLy8gdGhlIGVuZCBvZiB0aGUgYnVmZmVyDQogIFNlbmRQYWNrZXQgKGdPdXRCdWZmZXIpOw0KDQogIHJldHVybiBDb3VudDsNCn0NCg0KLyoqDQogIFByb2Nlc3MgInFYZmVyOm9iamVjdDpyZWFkOmFubmV4Om9mZnNldCxsZW5ndGgiIHJlcXVlc3QuDQoNCiAgUmV0dXJucyBhbiBYTUwgZG9jdW1lbnQgdGhhdCBjb250YWlucyBsb2FkZWQgbGlicmFyaWVzLiBJbiBvdXIgY2FzZSBpdCBpcw0KICBpbmZvbXJhdGlvbiBpbiB0aGUgRUZJIERlYnVnIElubWFnZSBUYWJsZSBjb252ZXJ0ZWQgaW50byBhbiBYTUwgZG9jdW1lbnQuDQoNCiAgR0RCIHdpbGwgY2FsbCB3aXRoIGFuIGFyYml0cmFyeSBsZW5ndGggKGl0IGNhbid0IGtub3cgdGhlIHJlYWwgbGVuZ3RoIGFuZA0KICB3aWxsIHJlcGx5IHdpdGggY2h1bmtzIG9mIFhNTCB0aGF0IGFyZSBlYXN5IGZvciB1cyB0byBkZWFsIHdpdGguIEdkYiB3aWxsDQogIGtlZXAgY2FsbGluZyB1bnRpbCB3ZSBzYXkgd2UgYXJlIGRvbmUuIFhNTCBkb2MgbG9va3MgbGlrZToNCg0KICA8bGlicmFyeS1saXN0Pg0KICAgIDxsaWJyYXJ5IG5hbWU9Ii9hL2EvYy9kLmRTWU0iPjxzZWdtZW50IGFkZHJlc3M9IjB4MTAwMDAwMDAiLz48L2xpYnJhcnk+DQogICAgPGxpYnJhcnkgbmFtZT0iL2EvbS9lL2UucGRiIj48c2VnbWVudCBhZGRyZXNzPSIweDIwMDAwMDAwIi8+PC9saWJyYXJ5Pg0KICAgIDxsaWJyYXJ5IG5hbWU9Ii9hL2wvZi9mLmRsbCI+PHNlZ21lbnQgYWRkcmVzcz0iMHgzMDAwMDAwMCIvPjwvbGlicmFyeT4NCiAgPC9saWJyYXJ5LWxpc3Q+DQoNCiAgU2luY2Ugd2UgY2FuIG5vdCBhbGxvY2F0ZSBtZW1vcnkgaW4gaW50ZXJ1cHQgY29udGV4dCB0aGlzIG1vZHVsZSBoYXMNCiAgYXNzdW1wdGlvbnMgYWJvdXQgaG93IGl0IHdpbGwgZ2V0IGNhbGxlZDoNCiAgMSkgTGVuZ3RoIHdpbGwgZ2VuZXJhbGx5IGJlIG1heCByZW1vdGUgcGFja2V0IHNpemUgKGJpZyBlbm91Z2gpDQogIDIpIEZpcnN0IE9mZnNldCBvZiBhbiBYTUwgZG9jdW1lbnQgcmVhZCBuZWVkcyB0byBiZSAwDQogIDMpIFRoaXMgY29kZSB3aWxsIHJldHVybiBiYWNrIHNtYWxsIGNodW5rcyBvZiB0aGUgWE1MIGRvY3VtZW50IG9uIGV2ZXJ5IHJlYWQuDQogICAgIEVhY2ggc3Vic2VxZW50IGNhbGwgd2lsbCBhc2sgZm9yIHRoZSBuZXh0IGF2YWlsYWJsZSBwYXJ0IG9mIHRoZSBkb2N1bWVudC4NCg0KICBOb3RlOiBUaGUgb25seSB2YXJpYWJsZSBzaXplIGVsZW1lbnQgaW4gdGhlIFhNTCBpczoNCiAgIiAgPGxpYnJhcnkgbmFtZT1cIiVzXCI+PHNlZ21lbnQgYWRkcmVzcz1cIiVwXCIvPjwvbGlicmFyeT5cbiIgYW5kIGl0IGlzDQogIGJhc2VkIG9uIHRoZSBmaWxlIHBhdGggYW5kIG5hbWUgb2YgdGhlIHN5bWJvbCBmaWxlLiBJZiB0aGUgc3ltYm9sIGZpbGUgbmFtZQ0KICBpcyBiaWdnZXIgdGhhbiB0aGUgbWF4IGdkYiByZW1vdGUgcGFja2V0IHNpemUgd2UgY291bGQgdXBkYXRlIHRoaXMgY29kZQ0KICB0byByZXNwb25kIGJhY2sgaW4gY2h1bmtzLg0KDQogQHBhcmFtIE9mZnNldCAgb2Zmc2V0IGludG8gc3BlY2lhbCBkYXRhIGFyZWENCiBAcGFyYW0gTGVuZ3RoICBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZCBzdGFydGluZyBhdCBPZmZzZXQNCg0KICoqLw0KVk9JRA0KUXhmZXJMaWJyYXJ5ICgNCiAgSU4gIFVJTlROICAgT2Zmc2V0LA0KICBJTiAgVUlOVE4gICBMZW5ndGgNCiAgKQ0Kew0KICBnUGFja2V0cVhmZXJMaWJyYXJ5T2Zmc2V0ICs9IGdYZmVyT2JqZWN0UmVhZFJlc3BvbnNlICgnbScsICI8bGlicmFyeS1saXN0PlxuIik7DQogIGdQYWNrZXRxWGZlckxpYnJhcnlPZmZzZXQgKz0gZ1hmZXJPYmplY3RSZWFkUmVzcG9uc2UgKCdtJywgcVhmZXJIYWNrKTsNCiAgZ1hmZXJPYmplY3RSZWFkUmVzcG9uc2UgKCdsJywgIjwvbGlicmFyeS1saXN0PlxuIik7DQogIGdQYWNrZXRxWGZlckxpYnJhcnlPZmZzZXQgPSAwOw0KfQ0KDQovKioNCiBUcmFuc2ZlciBsZW5ndGggYnl0ZXMgb2YgaW5wdXQgYnVmZmVyLCBzdGFydGluZyBhdCBBZGRyZXNzLCB0byBtZW1vcnkuDQoNCiBAcGFyYW0gICAgIGxlbmd0aCAgICAgICAgICAgICAgICAgIHRoZSBudW1iZXIgb2YgdGhlIGJ5dGVzIHRvIGJlIHRyYW5zZmVycmVkL3dyaXR0ZW4NCiBAcGFyYW0gICAgICphZGRyZXNzICAgICAgICAgICAgICAgIHRoZSBzdGFydCBhZGRyZXNzIG9mIHRoZSB0cmFuc2ZlcnJpbmcvd3JpdGluZyB0aGUgbWVtb3J5DQogQHBhcmFtICAgICAqbmV3X2RhdGEgICAgICAgICAgICAgICB0aGUgbmV3IGRhdGEgdG8gYmUgd3JpdHRlbiB0byBtZW1vcnkNCiAqKi8NCg0KVk9JRA0KVHJhbnNmZXJGcm9tSW5CdWZUb01lbSAoDQogIElOICAgIFVJTlROICAgICAgICAgICAgICAgICAgICAgICBMZW5ndGgsDQogIElOICAgIHVuc2lnbmVkIGNoYXIgICAgICAgICAgICAgICAqQWRkcmVzcywNCiAgSU4gICAgQ0hBUjggICAgICAgICAgICAgICAgICAgICAgICpOZXdEYXRhDQogICkNCnsNCiAgQ0hBUjggYzE7DQogIENIQVI4IGMyOw0KDQogIHdoaWxlIChMZW5ndGgtLSA+IDApIHsNCiAgICBjMSA9IChDSEFSOClIZXhDaGFyVG9JbnQgKCpOZXdEYXRhKyspOw0KICAgIGMyID0gKENIQVI4KUhleENoYXJUb0ludCAoKk5ld0RhdGErKyk7DQoNCiAgICBpZiAoKGMxIDwgMCkgfHwgKGMyIDwgMCkpIHsNCiAgICAgIFNlbmRFcnJvciAoR0RCX0VCQURNRU1EQVRBKTsNCiAgICAgIHJldHVybjsNCiAgICB9DQogICAgKkFkZHJlc3MrKyA9IChVSU5UOCkoKGMxIDw8IDQpICsgYzIpOw0KICB9DQoNCiAgU2VuZFN1Y2Nlc3MoKTsNCn0NCg0KDQovKioNCiBUcmFuc2ZlciBMZW5ndGggYnl0ZXMgb2YgbWVtb3J5IHN0YXJ0aW5nIGF0IEFkZHJlc3MgdG8gYW4gb3V0cHV0IGJ1ZmZlciwgT3V0QnVmZmVyLiBUaGlzIGZ1bmN0aW9uIHdpbGwgZmluYWxseSBzZW5kIHRoZSBidWZmZXINCiBhcyBhIHBhY2tldC4NCg0KIEBwYXJhbSAgICAgTGVuZ3RoICAgICAgICAgICAgICAgICAgdGhlIG51bWJlciBvZiB0aGUgYnl0ZXMgdG8gYmUgdHJhbnNmZXJyZWQvcmVhZA0KIEBwYXJhbSAgICAgKmFkZHJlc3MgICAgICAgICAgICAgICAgcG9pbnRlciB0byB0aGUgc3RhcnQgYWRkcmVzcyBvZiB0aGUgdHJhbnNmZXJyaW5nL3JlYWRpbmcgdGhlIG1lbW9yeQ0KICoqLw0KDQpWT0lEDQpUcmFuc2ZlckZyb21NZW1Ub091dEJ1ZkFuZFNlbmQgKA0KICBJTiAgICBVSU5UTiAgICAgICAgICAgICAgICAgICAgICAgTGVuZ3RoLA0KICBJTiAgICB1bnNpZ25lZCBjaGFyICAgICAgICAgICAgICAgKkFkZHJlc3MNCiAgKQ0Kew0KICAvLyB0aGVyZSBhcmUgTGVuZ3RoIGJ5dGVzIGFuZCBldmVyeSBieXRlIGlzIHJlcHJlc2VudGVkIGFzIDIgaGV4IGNoYXJzDQogIENIQVI4ICAgT3V0QnVmZmVyW01BWF9CVUZfU0laRV07DQogIENIQVI4ICAgKk91dEJ1ZlB0cjsgICAgICAgICAgICAgLy8gcG9pbnRlciB0byB0aGUgb3V0cHV0IGJ1ZmZlcg0KICBDSEFSOCAgIENoYXI7DQoNCiAgT3V0QnVmUHRyID0gT3V0QnVmZmVyOw0KICB3aGlsZSAoTGVuZ3RoID4gMCkgew0KDQogICAgQ2hhciA9IG1IZXhUb1N0clsqQWRkcmVzcyA+PiA0XTsNCiAgICBpZiAoKENoYXIgPj0gJ0EnKSAmJiAoQ2hhciA8PSAnRicpKSB7DQogICAgICBDaGFyID0gQ2hhciAtICdBJyArICdhJzsNCiAgICB9DQogICAgKk91dEJ1ZlB0cisrID0gQ2hhcjsNCg0KICAgIENoYXIgPSBtSGV4VG9TdHJbKkFkZHJlc3MgJiAweDBmXTsNCiAgICBpZiAoKENoYXIgPj0gJ0EnKSAmJiAoQ2hhciA8PSAnRicpKSB7DQogICAgICBDaGFyID0gQ2hhciAtICdBJyArICdhJzsNCiAgICB9DQogICAgKk91dEJ1ZlB0cisrID0gQ2hhcjsNCg0KICAgIEFkZHJlc3MrKzsNCiAgICBMZW5ndGgtLTsNCiAgfQ0KDQogICpPdXRCdWZQdHIgPSAnXDAnIDsgIC8vIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlcg0KICBTZW5kUGFja2V0IChPdXRCdWZmZXIpOw0KfQ0KDQoNCg0KLyoqDQogIFNlbmQgYSBHREIgUmVtb3RlIFNlcmlhbCBQcm90b2NvbCBQYWNrZXQNCg0KICAkUGFja2V0RGF0YSNjaGVja3N1bSBQYWNrZXREYXRhIGlzIHBhc3NlZCBpbiBhbmQgdGhpcyBmdW5jdGlvbiBhZGRzIHRoZSBwYWNrZXQgcHJlZml4ICckJywNCiAgdGhlIHBhY2tldCB0ZW1pbmF0aW5nIGNoYXJhY3RlciAnIycgYW5kIHRoZSB0d28gZGlnaXQgY2hlY2tzdW0uDQoNCiAgSWYgYW4gYWNrICcrJyBpcyBub3Qgc2VudCByZXNlbmQgdGhlIHBhY2tldCwgYnV0IHRpbWVvdXQgZXZlbnR1YWxseSBzbyB3ZSBkb24ndCBlbmQgdXANCiAgaW4gYW4gaW5maW5pdCBsb29wLiBUaGlzIGlzIHNvIGlmIHlvdSB1bnBsdWcgdGhlIGRlYnVnZ2VyIGNvZGUganVzdCBrZWVwcyBydW5uaW5nDQoNCiAgQHBhcmFtIFBhY2tldERhdGEgICBQYXlsb2FkIGRhdGEgZm9yIHRoZSBwYWNrZXQNCg0KDQogIEByZXR2YWwgICAgICAgICAgICAgTnVtYmVyIG9mIGJ5dGVzIG9mIHBhY2tldCBkYXRhIHNlbnQuDQoNCioqLw0KVUlOVE4NClNlbmRQYWNrZXQgKA0KICBJTiAgQ0hBUjggKlBhY2tldERhdGENCiAgKQ0Kew0KICBVSU5UOCBDaGVja1N1bTsNCiAgVUlOVE4gVGltZW91dDsNCiAgQ0hBUjggKlB0cjsNCiAgQ0hBUjggVGVzdENoYXI7DQogIFVJTlROIENvdW50Ow0KDQogIFRpbWVvdXQgPSBQY2RHZXQzMiAoUGNkR2RiTWF4UGFja2V0UmV0cnlDb3VudCk7DQoNCiAgQ291bnQgPSAwOw0KICBkbyB7DQoNCiAgICBQdHIgPSBQYWNrZXREYXRhOw0KDQogICAgaWYgKFRpbWVvdXQtLSA9PSAwKSB7DQogICAgICAvLyBPbmx5IHRyeSBhIGZpbml0ZSBudW1iZXIgb2YgdGltZXMgc28gd2UgZG9uJ3QgZ2V0IHN0dWNrIGluIHRoZSBsb29wDQogICAgICByZXR1cm4gQ291bnQ7DQogICAgfQ0KDQogICAgLy8gUGFja2V0IHByZWZpeA0KICAgIEdkYlB1dENoYXIgKCckJyk7DQoNCiAgICBmb3IgKENoZWNrU3VtID0gMCwgQ291bnQgPTAgOyAqUHRyICE9ICdcMCc7IFB0cisrLCBDb3VudCsrKSB7DQogICAgICBHZGJQdXRDaGFyICgqUHRyKTsNCiAgICAgIENoZWNrU3VtID0gQ2hlY2tTdW0gKyAqUHRyOw0KICAgIH0NCg0KICAgIC8vIFBhY2tldCB0ZXJtaW5hdGluZyBjaGFyYWN0ZXIgYW5kIGNoZWNrc3VtDQogICAgR2RiUHV0Q2hhciAoJyMnKTsNCiAgICBHZGJQdXRDaGFyIChtSGV4VG9TdHJbQ2hlY2tTdW0gPj4gNF0pOw0KICAgIEdkYlB1dENoYXIgKG1IZXhUb1N0cltDaGVja1N1bSAmIDB4MEZdKTsNCg0KICAgIFRlc3RDaGFyID0gIEdkYkdldENoYXIgKCk7DQogIH0gd2hpbGUgKFRlc3RDaGFyICE9ICcrJyk7DQoNCiAgcmV0dXJuIENvdW50Ow0KfQ0KDQovKioNCiAgUmVjZWl2ZSBhIEdEQiBSZW1vdGUgU2VyaWFsIFByb3RvY29sIFBhY2tldA0KDQogICRQYWNrZXREYXRhI2NoZWNrc3VtIFBhY2tldERhdGEgaXMgcGFzc2VkIGluIGFuZCB0aGlzIGZ1bmN0aW9uIGFkZHMgdGhlIHBhY2tldCBwcmVmaXggJyQnLA0KICB0aGUgcGFja2V0IHRlbWluYXRpbmcgY2hhcmFjdGVyICcjJyBhbmQgdGhlIHR3byBkaWdpdCBjaGVja3N1bS4NCg0KICBJZiBob3N0IHJlLXN0YXJ0cyBzZW5kaW5nIGEgcGFja2V0IHdpdGhvdXQgZW5kaW5nIHRoZSBwcmV2aW91cyBwYWNrZXQsIG9ubHkgdGhlIGxhc3QgdmFsaWQgcGFja2V0IGlzIHByb2Nlc3NlZC4NCiAgKEluIG90aGVyIHdvcmRzLCBpZiByZWNlaXZlZCBwYWNrZXQgaXMgJyQxMjM0NSQxMjM0NSQxMjM0NTYjY2hlY2tzdW0nLCBvbmx5ICckMTIzNDU2I2NoZWNrc3VtJyB3aWxsIGJlIHByb2Nlc3NlZC4pDQoNCiAgSWYgYW4gYWNrICcrJyBpcyBub3Qgc2VudCByZXNlbmQgdGhlIHBhY2tldA0KDQogIEBwYXJhbSBQYWNrZXREYXRhICAgUGF5bG9hZCBkYXRhIGZvciB0aGUgcGFja2V0DQoNCiAgQHJldHZhbCAgICAgICAgICAgICBOdW1iZXIgb2YgYnl0ZXMgb2YgcGFja2V0IGRhdGEgcmVjZWl2ZWQuDQoNCioqLw0KVUlOVE4NClJlY2VpdmVQYWNrZXQgKA0KICBPVVQgIENIQVI4ICpQYWNrZXREYXRhLA0KICBJTiAgIFVJTlROIFBhY2tldERhdGFTaXplDQogKQ0Kew0KICBVSU5UOCBDaGVja1N1bTsNCiAgVUlOVE4gSW5kZXg7DQogIENIQVI4IENoYXI7DQogIENIQVI4IFN1bVN0cmluZ1szXTsNCiAgQ0hBUjggVGVzdENoYXI7DQoNCiAgWmVyb01lbSAoUGFja2V0RGF0YSwgUGFja2V0RGF0YVNpemUpOw0KDQogIGZvciAoOzspIHsNCiAgICAgIC8vIHdhaXQgZm9yIHRoZSBzdGFydCBvZiBhIHBhY2tldA0KICAgIFRlc3RDaGFyID0gR2RiR2V0Q2hhciAoKTsNCiAgICB3aGlsZSAoVGVzdENoYXIgIT0gJyQnKSB7DQogICAgICBUZXN0Q2hhciA9IEdkYkdldENoYXIgKCk7DQogICAgfTsNCg0KICByZXRyeToNCiAgICBmb3IgKEluZGV4ID0gMCwgQ2hlY2tTdW0gPSAwOyBJbmRleCA8IChQYWNrZXREYXRhU2l6ZSAtIDEpOyBJbmRleCsrKSB7DQogICAgICBDaGFyID0gR2RiR2V0Q2hhciAoKTsNCiAgICAgIGlmIChDaGFyID09ICckJykgew0KICAgICAgICBnb3RvIHJldHJ5Ow0KICAgICAgfQ0KICAgICAgaWYgKENoYXIgPT0gJyMnKSB7DQogICAgICAgIGJyZWFrOw0KICAgICAgfQ0KDQogICAgICBQYWNrZXREYXRhW0luZGV4XSA9IENoYXI7DQogICAgICBDaGVja1N1bSA9IENoZWNrU3VtICsgQ2hhcjsNCiAgICB9DQogICAgUGFja2V0RGF0YVtJbmRleF0gPSAnXDAnOw0KDQogICAgaWYgKEluZGV4ID09IFBhY2tldERhdGFTaXplKSB7DQogICAgICBjb250aW51ZTsNCiAgICB9DQoNCiAgICBTdW1TdHJpbmdbMF0gPSBHZGJHZXRDaGFyICgpOw0KICAgIFN1bVN0cmluZ1sxXSA9IEdkYkdldENoYXIgKCk7DQogICAgU3VtU3RyaW5nWzJdID0gJ1wwJzsNCg0KICAgIGlmIChBc2NpaVN0ckhleFRvVWludG4gKFN1bVN0cmluZykgPT0gQ2hlY2tTdW0pIHsNCiAgICAgIC8vIEFjazogU3VjY2Vzcw0KICAgICAgR2RiUHV0Q2hhciAoJysnKTsNCg0KICAgICAgLy8gTnVsbCB0ZXJtaW5hdGUgdGhlIGNhbGxlcnMgc3RyaW5nDQogICAgICBQYWNrZXREYXRhW0luZGV4XSA9ICdcMCc7DQogICAgICByZXR1cm4gSW5kZXg7DQogICAgfSBlbHNlIHsNCiAgICAgIC8vIEFjazogRmFpbHVyZQ0KICAgICAgR2RiUHV0Q2hhciAoJy0nKTsNCiAgICB9DQogIH0NCg0KICAvL3JldHVybiAwOw0KfQ0KDQoNCi8qKg0KIEVtcHRpZXMgdGhlIGdpdmVuIGJ1ZmZlcg0KIEBwYXJhbSAgIEJ1ZiAgICAgICAgICBwb2ludGVyIHRvIHRoZSBmaXJzdCBlbGVtZW50IGluIGJ1ZmZlciB0byBiZSBlbXB0aWVkDQogKiovDQpWT0lEDQpFbXB0eUJ1ZmZlciAoDQogIElOICBDSEFSOCAgICAgICAgICAgKkJ1Zg0KICApDQp7DQogICpCdWYgPSAnXDAnOw0KfQ0KDQoNCi8qKg0KIENvbnZlcnRzIGFuIDgtYml0IEhleCBDaGFyIGludG8gYSBJTlROLg0KDQogQHBhcmFtICAgQ2hhciB0aGUgaGV4IGNoYXJhY3RlciB0byBiZSBjb252ZXJ0ZWQgaW50byBVSU5UTg0KIEByZXR2YWwgIGEgSU5UTiwgZnJvbSAwIHRvIDE1LCB0aGF0IGNvcnJlc3Nwb25kcyB0byBDaGFyDQogLTEgaWYgQ2hhciBpcyBub3QgYSBoZXggY2hhcmFjdGVyDQogKiovDQpJTlRODQpIZXhDaGFyVG9JbnQgKA0KICBJTiAgQ0hBUjggICAgICAgICAgIENoYXINCiAgKQ0Kew0KICBpZiAoKENoYXIgPj0gJ0EnKSAmJiAoQ2hhciA8PSAnRicpKSB7DQogICAgcmV0dXJuIENoYXIgLSAnQScgKyAxMDsNCiAgfSBlbHNlIGlmICgoQ2hhciA+PSAnYScpICYmIChDaGFyIDw9ICdmJykpIHsNCiAgICByZXR1cm4gQ2hhciAtICdhJyArIDEwOw0KICB9IGVsc2UgaWYgKChDaGFyID49ICcwJykgJiYgKENoYXIgPD0gJzknKSkgew0KICAgIHJldHVybiBDaGFyIC0gJzAnOw0KICB9IGVsc2UgeyAvLyBpZiBub3QgYSBoZXggdmFsdWUsIHJldHVybiBhIG5lZ2F0aXZlIHZhbHVlDQogICAgcmV0dXJuIC0xOw0KICB9DQp9DQoNCiAgLy8gJ0UnICsgdGhlIGJpZ2dlc3QgZXJyb3IgbnVtYmVyIGlzIDI1NSwgc28gaXRzIDIgaGV4IGRpZ2l0cyArIGJ1ZmZlciBlbmQNCkNIQVI4ICpnRXJyb3IgPSAiRV9fIjsNCg0KLyoqICdFIE5OJw0KIFNlbmQgYW4gZXJyb3Igd2l0aCB0aGUgZ2l2ZW4gZXJyb3IgbnVtYmVyIGFmdGVyIGNvbnZlcnRpbmcgdG8gaGV4Lg0KIFRoZSBlcnJvciBudW1iZXIgaXMgcHV0IGludG8gdGhlIGJ1ZmZlciBpbiBoZXguICcyNTUnIGlzIHRoZSBiaWdnZXN0IGVycm5vIHdlIGNhbiBzZW5kLg0KIGV4OiAxNjIgd2lsbCBiZSBzZW50IGFzIEEyLg0KDQogQHBhcmFtICAgZXJybm8gICAgICAgICAgIHRoZSBlcnJvciBudW1iZXIgdGhhdCB3aWxsIGJlIHNlbnQNCiAqKi8NClZPSUQNCkVGSUFQSQ0KU2VuZEVycm9yICgNCiAgSU4gIFVJTlQ4ICAgICAgICAgICAgICBFcnJvck51bQ0KICApDQp7DQogIC8vDQogIC8vIFJlcGxhY2UgXywgb3Igb2xkIGRhdGEsIHdpdGggY3VycmVudCBlcnJubw0KICAvLw0KICBnRXJyb3JbMV0gPSBtSGV4VG9TdHIgW0Vycm9yTnVtID4+IDRdOw0KICBnRXJyb3JbMl0gPSBtSGV4VG9TdHIgW0Vycm9yTnVtICYgMHgwZl07DQoNCiAgU2VuZFBhY2tldCAoZ0Vycm9yKTsgLy8gc2VuZCBidWZmZXINCn0NCg0KDQoNCi8qKg0KIFNlbmQgJ09LJyB3aGVuIHRoZSBmdW5jdGlvbiBpcyBkb25lIGV4ZWN1dGluZyBzdWNjZXNzZnVsbHkuDQogKiovDQpWT0lEDQpFRklBUEkNClNlbmRTdWNjZXNzICgNCiAgVk9JRA0KICApDQp7DQogIFNlbmRQYWNrZXQgKCJPSyIpOyAvLyBzZW5kIGJ1ZmZlcg0KfQ0KDQoNCi8qKg0KIFNlbmQgZW1wdHkgcGFja2V0IHRvIHNwZWNpZnkgdGhhdCBwYXJ0aWN1bGFyIGNvbW1hbmQvZnVuY3Rpb25hbGl0eSBpcyBub3Qgc3VwcG9ydGVkLg0KICoqLw0KVk9JRA0KRUZJQVBJDQpTZW5kTm90U3VwcG9ydGVkICgNCiAgVk9JRA0KICApDQp7DQogIFNlbmRQYWNrZXQgKCIiKTsNCn0NCg0KDQoNCg0KDQovKioNCiBUcmFuc2xhdGVzIHRoZSBFRkkgbWFwcGluZyB0byBHREIgbWFwcGluZw0KDQogQHBhcmFtICAgRUZJRXhjZXB0aW9uVHlwZSAgICBFRkkgRXhjZXB0aW9uIHRoYXQgaXMgYmVpbmcgcHJvY2Vzc2VkDQogQHJldHZhbCAgVUlOVE4gdGhhdCBjb3JyZXNwb25kcyB0byBFRklFeGNlcHRpb25UeXBlJ3MgR0RCIGV4Y2VwdGlvbiB0eXBlIG51bWJlcg0KICoqLw0KVUlOVDgNCkNvbnZlcnRFRkl0b0dEQnR5cGUgKA0KICBJTiAgRUZJX0VYQ0VQVElPTl9UWVBFICAgICAgRUZJRXhjZXB0aW9uVHlwZQ0KICApDQp7DQogIFVJTlROIGk7DQoNCiAgZm9yIChpPTA7IGkgPCBNYXhFZmlFeGNlcHRpb24oKSA7IGkrKykgew0KICAgIGlmIChnRXhjZXB0aW9uVHlwZVtpXS5FeGNlcHRpb24gPT0gRUZJRXhjZXB0aW9uVHlwZSkgew0KICAgICAgcmV0dXJuIGdFeGNlcHRpb25UeXBlW2ldLlNpZ25hbE5vOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gR0RCX1NJR1RSQVA7IC8vIHRoaXMgaXMgYSBHREIgdHJhcA0KfQ0KDQoNCi8qKiAibSBhZGRyLGxlbmd0aCINCiBGaW5kIHRoZSBMZW5ndGggb2YgdGhlIGFyZWEgdG8gcmVhZCBhbmQgdGhlIHN0YXJ0IGFkZHJlcy4gRmluYWxseSwgcGFzcyB0aGVtIHRvDQogYW5vdGhlciBmdW5jdGlvbiwgVHJhbnNmZXJGcm9tTWVtVG9PdXRCdWZBbmRTZW5kLCB0aGF0IHdpbGwgcmVhZCBmcm9tIHRoYXQgbWVtb3J5IHNwYWNlIGFuZA0KIHNlbmQgaXQgYXMgYSBwYWNrZXQuDQogKiovDQoNClZPSUQNCkVGSUFQSQ0KUmVhZEZyb21NZW1vcnkgKA0KICBDSEFSOCAqUGFja2V0RGF0YQ0KICApDQp7DQogIFVJTlROIEFkZHJlc3M7DQogIFVJTlROIExlbmd0aDsNCiAgQ0hBUjggQWRkcmVzc0J1ZmZlcltNQVhfQUREUl9TSVpFXTsgLy8gdGhlIGJ1ZmZlciB0aGF0IHdpbGwgaG9sZCB0aGUgYWRkcmVzcyBpbiBoZXggY2hhcnMNCiAgQ0hBUjggKkFkZHJCdWZQdHI7IC8vIHBvaW50ZXIgdG8gdGhlIGFkZHJlc3MgYnVmZmVyDQogIENIQVI4ICpJbkJ1ZlB0cjsgLy8vIHBvaW50ZXIgdG8gdGhlIGlucHV0IGJ1ZmZlcg0KDQogIEFkZHJCdWZQdHIgPSBBZGRyZXNzQnVmZmVyOw0KICBJbkJ1ZlB0ciA9ICZQYWNrZXREYXRhWzFdOw0KICB3aGlsZSAoKkluQnVmUHRyICE9ICcsJykgew0KICAgICpBZGRyQnVmUHRyKysgPSAqSW5CdWZQdHIrKzsNCiAgfQ0KICAqQWRkckJ1ZlB0ciA9ICdcMCc7DQoNCiAgSW5CdWZQdHIrKzsgLy8gdGhpcyBza2lwcyAnLCcgaW4gdGhlIGJ1ZmZlcg0KDQogIC8qIEVycm9yIGNoZWNraW5nICovDQogIGlmIChBc2NpaVN0ckxlbihBZGRyZXNzQnVmZmVyKSA+PSBNQVhfQUREUl9TSVpFKSB7DQogICAgU2VuZEVycm9yIChHREJfRUJBRE1FTUFERFJCVUZTSVpFKTsNCiAgICByZXR1cm47DQogIH0NCg0KICAvLyAyID0gJ20nICsgJywnDQogIGlmIChBc2NpaVN0ckxlbihQYWNrZXREYXRhKSAtIEFzY2lpU3RyTGVuKEFkZHJlc3NCdWZmZXIpIC0gMiA+PSBNQVhfTEVOR1RIX1NJWkUpIHsNCiAgICBTZW5kRXJyb3IgKEdEQl9FQkFETUVNTEVOR1RIKTsNCiAgICByZXR1cm47DQogIH0NCg0KICBBZGRyZXNzID0gQXNjaWlTdHJIZXhUb1VpbnRuIChBZGRyZXNzQnVmZmVyKTsNCiAgTGVuZ3RoID0gQXNjaWlTdHJIZXhUb1VpbnRuIChJbkJ1ZlB0cik7DQoNCiAgVHJhbnNmZXJGcm9tTWVtVG9PdXRCdWZBbmRTZW5kIChMZW5ndGgsICh1bnNpZ25lZCBjaGFyICopQWRkcmVzcyk7DQp9DQoNCg0KLyoqICJNIGFkZHIsbGVuZ3RoIDpYWC4uLiINCiBGaW5kIHRoZSBMZW5ndGggb2YgdGhlIGFyZWEgaW4gYnl0ZXMgdG8gd3JpdGUgYW5kIHRoZSBzdGFydCBhZGRyZXMuIEZpbmFsbHksIHBhc3MgdGhlbSB0bw0KIGFub3RoZXIgZnVuY3Rpb24sIFRyYW5zZmVyRnJvbUluQnVmVG9NZW0sIHRoYXQgd2lsbCB3cml0ZSB0byB0aGF0IG1lbW9yeSBzcGFjZSB0aGUgaW5mbyBpbg0KIHRoZSBpbnB1dCBidWZmZXIuDQogKiovDQpWT0lEDQpFRklBUEkNCldyaXRlVG9NZW1vcnkgKA0KICBJTiBDSEFSOCAqUGFja2V0RGF0YQ0KICApDQp7DQogIFVJTlROIEFkZHJlc3M7DQogIFVJTlROIExlbmd0aDsNCiAgVUlOVE4gTWVzc2FnZUxlbmd0aDsNCiAgQ0hBUjggQWRkcmVzc0J1ZmZlcltNQVhfQUREUl9TSVpFXTsgLy8gdGhlIGJ1ZmZlciB0aGF0IHdpbGwgaG9sZCB0aGUgQWRkcmVzcyBpbiBoZXggY2hhcnMNCiAgQ0hBUjggTGVuZ3RoQnVmZmVyW01BWF9MRU5HVEhfU0laRV07IC8vIHRoZSBidWZmZXIgdGhhdCB3aWxsIGhvbGQgdGhlIExlbmd0aCBpbiBoZXggY2hhcnMNCiAgQ0hBUjggKkFkZHJCdWZQdHI7IC8vIHBvaW50ZXIgdG8gdGhlIEFkZHJlc3MgYnVmZmVyDQogIENIQVI4ICpMZW5ndGhCdWZQdHI7IC8vIHBvaW50ZXIgdG8gdGhlIExlbmd0aCBidWZmZXINCiAgQ0hBUjggKkluQnVmUHRyOyAvLy8gcG9pbnRlciB0byB0aGUgaW5wdXQgYnVmZmVyDQoNCiAgQWRkckJ1ZlB0ciA9IEFkZHJlc3NCdWZmZXI7DQogIExlbmd0aEJ1ZlB0ciA9IExlbmd0aEJ1ZmZlcjsNCiAgSW5CdWZQdHIgPSAmUGFja2V0RGF0YVsxXTsNCg0KICB3aGlsZSAoKkluQnVmUHRyICE9ICcsJykgew0KICAgICpBZGRyQnVmUHRyKysgPSAqSW5CdWZQdHIrKzsNCiAgfQ0KICAqQWRkckJ1ZlB0ciA9ICdcMCc7DQoNCiAgSW5CdWZQdHIrKzsgLy8gdGhpcyBza2lwcyAnLCcgaW4gdGhlIGJ1ZmZlcg0KDQogIHdoaWxlICgqSW5CdWZQdHIgIT0gJzonKSB7DQogICAgKkxlbmd0aEJ1ZlB0cisrID0gKkluQnVmUHRyKys7DQogIH0NCiAgKkxlbmd0aEJ1ZlB0ciA9ICdcMCc7DQoNCiAgSW5CdWZQdHIrKzsgLy8gdGhpcyBza2lwcyAnOicgaW4gdGhlIGJ1ZmZlcg0KDQogIEFkZHJlc3MgPSBBc2NpaVN0ckhleFRvVWludG4gKEFkZHJlc3NCdWZmZXIpOw0KICBMZW5ndGggPSBBc2NpaVN0ckhleFRvVWludG4gKExlbmd0aEJ1ZmZlcik7DQoNCiAgLyogRXJyb3IgY2hlY2tpbmcgKi8NCg0KICAvL0NoZWNrIGlmIEFkZHJlc3MgaXMgbm90IHRvbyBsb25nLg0KICBpZiAoQXNjaWlTdHJMZW4oQWRkcmVzc0J1ZmZlcikgPj0gTUFYX0FERFJfU0laRSkgew0KICAgIFNlbmRFcnJvciAoR0RCX0VCQURNRU1BRERSQlVGU0laRSk7DQogICAgcmV0dXJuOw0KICB9DQoNCiAgLy9DaGVjayBpZiBtZXNzYWdlIGxlbmd0aCBpcyBub3QgdG9vIGxvbmcNCiAgaWYgKEFzY2lpU3RyTGVuKExlbmd0aEJ1ZmZlcikgPj0gTUFYX0xFTkdUSF9TSVpFKSB7DQogICAgU2VuZEVycm9yIChHREJfRUJBRE1FTUxFTkdCVUZTSVpFKTsNCiAgICByZXR1cm47DQogIH0NCg0KICAvLyBDaGVjayBpZiBNZXNzYWdlIGlzIG5vdCB0b28gbG9uZy9zaG9ydC4NCiAgLy8gMyA9ICdNJyArICcsJyArICc6Jw0KICBNZXNzYWdlTGVuZ3RoID0gKEFzY2lpU3RyTGVuKFBhY2tldERhdGEpIC0gQXNjaWlTdHJMZW4oQWRkcmVzc0J1ZmZlcikgLSBBc2NpaVN0ckxlbihMZW5ndGhCdWZmZXIpIC0gMyk7DQogIGlmIChNZXNzYWdlTGVuZ3RoICE9ICgyKkxlbmd0aCkpIHsNCiAgICAvL01lc3NhZ2UgdG9vIGxvbmcvc2hvcnQuIE5ldyBkYXRhIGlzIG5vdCB0aGUgcmlnaHQgc2l6ZS4NCiAgICBTZW5kRXJyb3IgKEdEQl9FQkFETUVNREFUQVNJWkUpOw0KICAgIHJldHVybjsNCiAgfQ0KICBUcmFuc2ZlckZyb21JbkJ1ZlRvTWVtIChMZW5ndGgsICh1bnNpZ25lZCBjaGFyICopQWRkcmVzcywgSW5CdWZQdHIpOw0KfQ0KDQovKioNCiAgUGFyc2VzIGJyZWFrcG9pbnQgcGFja2V0IGRhdGEgYW5kIGNhcHR1cmVzIEJyZWFrcG9pbnQgdHlwZSwgQWRkcmVzcyBhbmQgbGVuZ3RoLg0KICBJbiBjYXNlIG9mIGFuIGVycm9yLCBmdW5jdGlvbiByZXR1cm5zIHBhcnRpY3VsYXIgZXJyb3IgY29kZS4gUmV0dXJuaW5nIDAgbWVhbmluZw0KICBubyBlcnJvci4NCg0KICBAcGFyYW0gIFBhY2tldERhdGEgIFBvaW50ZXIgdG8gdGhlIHBheWxvYWQgZGF0YSBmb3IgdGhlIHBhY2tldC4NCiAgQHBhcmFtICBUeXBlICAgICAgICBCcmVha3BvaW50IHR5cGUNCiAgQHBhcmFtICBBZGRyZXNzICAgICBCcmVha3BvaW50IGFkZHJlc3MNCiAgQHBhcmFtICBMZW5ndGggICAgICBCcmVha3BvaW50IGxlbmd0aCBpbiBCeXRlcyAoMSBieXRlLCAyIGJ5dGUsIDQgYnl0ZSkNCg0KICBAcmV0dmFsIDEgICAgICAgICAgIFN1Y2Nlc3MNCiAgQHJldHZhbCB7b3RoZXJ9ICAgICBQYXJ0aWN1bGFyIGVycm9yIGNvZGUNCg0KKiovDQpVSU5UTg0KUGFyc2VCcmVha3BvaW50UGFja2V0ICgNCiAgSU4gIENIQVI4ICpQYWNrZXREYXRhLA0KICBPVVQgVUlOVE4gKlR5cGUsDQogIE9VVCBVSU5UTiAqQWRkcmVzcywNCiAgT1VUIFVJTlROICpMZW5ndGgNCiAgKQ0Kew0KICBDSEFSOCBBZGRyZXNzQnVmZmVyW01BWF9BRERSX1NJWkVdOw0KICBDSEFSOCAqQWRkcmVzc0J1ZmZlclB0cjsNCiAgQ0hBUjggKlBhY2tldERhdGFQdHI7DQoNCiAgUGFja2V0RGF0YVB0ciA9ICZQYWNrZXREYXRhWzFdOw0KICBBZGRyZXNzQnVmZmVyUHRyID0gQWRkcmVzc0J1ZmZlcjsNCg0KICAqVHlwZSA9IEFzY2lpU3RySGV4VG9VaW50biAoUGFja2V0RGF0YVB0cik7DQoNCiAgLy9CcmVha3BvaW50L3dhdGNocG9pbnQgdHlwZSBzaG91bGQgYmUgYmV0d2VlbiAwIHRvIDQNCiAgaWYgKCpUeXBlID4gNCkgew0KICAgIHJldHVybiAyMjsgLy9FSU5WQUw6IEludmFsaWQgYXJndW1lbnQuDQogIH0NCg0KICAvL1NraXAgJywnIGluIHRoZSBidWZmZXIuDQogIHdoaWxlICgqUGFja2V0RGF0YVB0cisrICE9ICcsJyk7DQoNCiAgLy9QYXJzZSBBZGRyZXNzIGluZm9ybWF0aW9uDQogIHdoaWxlICgqUGFja2V0RGF0YVB0ciAhPSAnLCcpIHsNCiAgICAqQWRkcmVzc0J1ZmZlclB0cisrID0gKlBhY2tldERhdGFQdHIrKzsNCiAgfQ0KICAqQWRkcmVzc0J1ZmZlclB0ciA9ICdcMCc7DQoNCiAgLy9DaGVjayBpZiBBZGRyZXNzIGlzIG5vdCB0b28gbG9uZy4NCiAgaWYgKEFzY2lpU3RyTGVuKEFkZHJlc3NCdWZmZXIpID49IE1BWF9BRERSX1NJWkUpIHsNCiAgICByZXR1cm4gNDA7IC8vRU1TR1NJWkU6IE1lc3NhZ2Ugc2l6ZSB0b28gbG9uZy4NCiAgfQ0KDQogICpBZGRyZXNzID0gQXNjaWlTdHJIZXhUb1VpbnRuIChBZGRyZXNzQnVmZmVyKTsNCg0KICBQYWNrZXREYXRhUHRyKys7IC8vVGhpcyBza2lwcyAsIGluIHRoZSBidWZmZXINCg0KICAvL1BhcnNlIExlbmd0aCBpbmZvcm1hdGlvbg0KICAqTGVuZ3RoID0gQXNjaWlTdHJIZXhUb1VpbnRuIChQYWNrZXREYXRhUHRyKTsNCg0KICAvL0xlbmd0aCBzaG91bGQgYmUgMSwgMiBvciA0IGJ5dGVzDQogIGlmICgqTGVuZ3RoID4gNCkgew0KICAgIHJldHVybiAyMjsgLy9FSU5WQUw6IEludmFsaWQgYXJndW1lbnQNCiAgfQ0KDQogIHJldHVybiAwOyAvLzAgPSBObyBlcnJvcg0KfQ0KDQoNCg0KLyoqDQogU2VuZCB0aGUgVCBzaWduYWwgd2l0aCB0aGUgZ2l2ZW4gZXhjZXB0aW9uIHR5cGUgKGluIGdkYiBvcmRlcikgYW5kIHBvc3NpYmx5IHdpdGggbjpyIHBhaXJzIHJlbGF0ZWQgdG8gdGhlIHdhdGNocG9pbnRzDQoNCiBAcGFyYW0gIFN5c3RlbUNvbnRleHQgICAgICAgIFJlZ2lzdGVyIGNvbnRlbnQgYXQgdGltZSBvZiB0aGUgZXhjZXB0aW9uDQogQHBhcmFtICBHZGJFeGNlcHRpb25UeXBlICAgICBHREIgZXhjZXB0aW9uIHR5cGUNCiAqKi8NClZPSUQNCkdkYlNlbmRUU2lnbmFsICgNCiAgSU4gIEVGSV9TWVNURU1fQ09OVEVYVCAgU3lzdGVtQ29udGV4dCwNCiAgSU4gIFVJTlQ4ICAgICAgICAgICAgICAgR2RiRXhjZXB0aW9uVHlwZQ0KICApDQp7DQogIENIQVI4IFRTaWduYWxCdWZmZXJbMTI4XTsNCiAgQ0hBUjggKlRTaWduYWxQdHI7DQoNCiAgVFNpZ25hbFB0ciA9ICZUU2lnbmFsQnVmZmVyWzBdOw0KDQogIC8vQ29uc3RydWN0IFRTaWduYWwgcGFja2V0DQogICpUU2lnbmFsUHRyKysgPSAnVCc7DQoNCiAgLy8NCiAgLy8gcmVwbGFjZSBfLCBvciBwcmV2aW91cyB2YWx1ZSwgd2l0aCBFeGNlcHRpb24gdHlwZQ0KICAvLw0KICAqVFNpZ25hbFB0cisrID0gbUhleFRvU3RyIFtHZGJFeGNlcHRpb25UeXBlID4+IDRdOw0KICAqVFNpZ25hbFB0cisrID0gbUhleFRvU3RyIFtHZGJFeGNlcHRpb25UeXBlICYgMHgwZl07DQoNCiAgUHJvY2Vzc29yU2VuZFRTaWduYWwgKFN5c3RlbUNvbnRleHQsIEdkYkV4Y2VwdGlvblR5cGUsIFRTaWduYWxQdHIsIHNpemVvZiAoVFNpZ25hbEJ1ZmZlcikgLSAyKTsNCg0KICBTZW5kUGFja2V0IChUU2lnbmFsQnVmZmVyKTsNCn0NCg0KVk9JRA0KR2RiRldyaXRlICgNCiAgSU4gIFVJTlROIEZkLA0KICBJTiAgQ0hBUjggKkRhdGEsDQogIElOICBVSU5UTiBEYXRhU2l6ZQ0KICApDQp7DQogIENIQVI4IEJ1ZmZlclsxMjhdOw0KDQogIEFzY2lpU1ByaW50IChCdWZmZXIsIHNpemVvZiAoQnVmZmVyKSwgIkZ3cml0ZSwleCwleCwleCIsIEZkLCBEYXRhLCBEYXRhU2l6ZSk7DQogIFNlbmRQYWNrZXQgKEJ1ZmZlcik7DQoNCiAgZm9yKCA7IDsgKSB7DQogICAgUmVjZWl2ZVBhY2tldCAoZ0luQnVmZmVyLCBNQVhfQlVGX1NJWkUpOw0KDQogICAgc3dpdGNoIChnSW5CdWZmZXJbMF0pIHsNCiAgICBjYXNlICdtJzoNCiAgICAgIFJlYWRGcm9tTWVtb3J5IChnSW5CdWZmZXIpOw0KICAgICAgYnJlYWs7DQoNCiAgICBjYXNlICdNJzoNCiAgICAgIFdyaXRlVG9NZW1vcnkgKGdJbkJ1ZmZlcik7DQogICAgICBicmVhazsNCg0KICAgIGNhc2UgJ0YnOg0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgfQ0KfQ0KDQoNClZPSUQNCkdkYkZQdXRTdHJpbmcgKA0KICBJTiBDSEFSOCAgKlN0cmluZw0KICApDQp7DQogIFVJTlROIExlbiA9IEFzY2lpU3RyU2l6ZSAoU3RyaW5nKTsNCg0KICBHZGJGV3JpdGUgKDIsIFN0cmluZywgTGVuKTsNCn0NCg0KDQovKioNCiBFeGNlcHRpb24gSGFubGRsZXIgZm9yIEdEQi4gSXQgd2lsbCBiZSBjYWxsZWQgZm9yIGFsbCBleGNlcHRpb25zDQogcmVnaXN0ZXJlZCB2aWEgdGhlIGdFeGNlcHRpb25UeXBlW10gYXJyYXkuDQoNCiBAcGFyYW0gRXhjZXB0aW9uVHlwZSAgICAgRXhjZXB0aW9uIHRoYXQgaXMgYmVpbmcgcHJvY2Vzc2VkDQogQHBhcmFtIFN5c3RlbUNvbnRleHQgICAgIFJlZ2lzdGVyIGNvbnRlbnQgYXQgdGltZSBvZiB0aGUgZXhjZXB0aW9uDQogKiovDQpWT0lEDQpFRklBUEkNCkdkYkV4Y2VwdGlvbkhhbmRsZXIgKA0KICBJTiAgRUZJX0VYQ0VQVElPTl9UWVBFICAgICAgICBFeGNlcHRpb25UeXBlLA0KICBJTiBPVVQgRUZJX1NZU1RFTV9DT05URVhUICAgICBTeXN0ZW1Db250ZXh0DQogICkNCnsNCiAgVUlOVDggICBHZGJFeGNlcHRpb25UeXBlOw0KICBDSEFSOCAgICpQdHI7DQoNCiAgaWYgKFByb2Nlc3NvckNvbnRyb2xDIChFeGNlcHRpb25UeXBlLCBTeXN0ZW1Db250ZXh0KSkgew0KICAgIC8vIFdlIHRyaWVkIHRvIHByb2Nlc3MgYSBjb250cm9sIEMgaGFuZGxlciBhbmQgdGhlcmUgaXMgbm90aGluZyB0byBkbw0KICAgIHJldHVybjsNCiAgfQ0KDQogIEdkYkV4Y2VwdGlvblR5cGUgPSBDb252ZXJ0RUZJdG9HREJ0eXBlIChFeGNlcHRpb25UeXBlKTsNCiAgR2RiU2VuZFRTaWduYWwgKFN5c3RlbUNvbnRleHQsIEdkYkV4Y2VwdGlvblR5cGUpOw0KDQogIGZvciggOyA7ICkgew0KICAgIFJlY2VpdmVQYWNrZXQgKGdJbkJ1ZmZlciwgTUFYX0JVRl9TSVpFKTsNCg0KICAgIHN3aXRjaCAoZ0luQnVmZmVyWzBdKSB7DQogICAgICBjYXNlICc/JzoNCiAgICAgICAgR2RiU2VuZFRTaWduYWwgKFN5c3RlbUNvbnRleHQsIEdkYkV4Y2VwdGlvblR5cGUpOw0KICAgICAgICBicmVhazsNCg0KICAgICAgY2FzZSAnYyc6DQogICAgICAgIENvbnRpbnVlQXRBZGRyZXNzIChTeXN0ZW1Db250ZXh0LCBnSW5CdWZmZXIpOw0KICAgICAgICByZXR1cm47DQoNCiAgICAgIGNhc2UgJ0QnOg0KICAgICAgICAvLyBnZGIgd2FudHMgdG8gZGlzY29ubmVjdCBzbyByZXR1cm4gIk9LIiBwYWNrZXQgc2luY2UuDQogICAgICAgIFNlbmRTdWNjZXNzICgpOw0KICAgICAgICByZXR1cm47DQoNCiAgICAgIGNhc2UgJ2cnOg0KICAgICAgICBSZWFkR2VuZXJhbFJlZ2lzdGVycyAoU3lzdGVtQ29udGV4dCk7DQogICAgICAgIGJyZWFrOw0KDQogICAgICBjYXNlICdHJzoNCiAgICAgICAgV3JpdGVHZW5lcmFsUmVnaXN0ZXJzIChTeXN0ZW1Db250ZXh0LCBnSW5CdWZmZXIpOw0KICAgICAgICBicmVhazsNCg0KICAgICAgY2FzZSAnSCc6DQogICAgICAgIC8vUmV0dXJuICJPSyIgcGFja2V0IHNpbmNlIHdlIGRvbid0IGhhdmUgbW9yZSB0aGFuIG9uZSB0aHJlYWQuDQogICAgICAgIFNlbmRTdWNjZXNzICgpOw0KICAgICAgICBicmVhazsNCg0KICAgICAgY2FzZSAnbSc6DQogICAgICAgIFJlYWRGcm9tTWVtb3J5IChnSW5CdWZmZXIpOw0KICAgICAgICBicmVhazsNCg0KICAgICAgY2FzZSAnTSc6DQogICAgICAgIFdyaXRlVG9NZW1vcnkgKGdJbkJ1ZmZlcik7DQogICAgICAgIGJyZWFrOw0KDQogICAgICBjYXNlICdQJzoNCiAgICAgICAgV3JpdGVOdGhSZWdpc3RlciAoU3lzdGVtQ29udGV4dCwgZ0luQnVmZmVyKTsNCiAgICAgICAgYnJlYWs7DQoNCiAgICAgIC8vDQogICAgICAvLyBTdGlsbCBkZWJ1Z2dpbmcgdGhpcyBjb2RlLiBOb3QgdXNlZCBpbiBEYXJ3aW4NCiAgICAgIC8vDQogICAgICBjYXNlICdxJzoNCiAgICAgICAgLy8gR2VuZXJhbCBRdWVyeSBQYWNrZXRzDQogICAgICAgIGlmIChBc2NpaVN0cm5DbXAgKGdJbkJ1ZmZlciwgInFTdXBwb3J0ZWQiLCAxMCkgPT0gMCkgew0KICAgICAgICAgIC8vIHJldHVybiB3aGF0IHdlIGN1cnJlbnRseSBzdXBwb3J0LCB3ZSBkb24ndCBwYXJzZSB3aGF0IGdkYiBzdXBvcnRzDQogICAgICAgICAgQXNjaWlTUHJpbnQgKGdPdXRCdWZmZXIsIE1BWF9CVUZfU0laRSwgInFYZmVyOmxpYnJhcmllczpyZWFkKztQYWNrZXRTaXplPSVkIiwgTUFYX0JVRl9TSVpFKTsNCiAgICAgICAgICBTZW5kUGFja2V0IChnT3V0QnVmZmVyKTsNCiAgICAgICAgfSBlbHNlIGlmIChBc2NpaVN0cm5DbXAgKGdJbkJ1ZmZlciwgInFYZmVyOmxpYnJhcmllczpyZWFkOjoiLCAyMikgPT0gMCkgew0KICAgICAgICAgIC8vIJFxWGZlcjpsaWJyYXJpZXM6cmVhZDo6b2Zmc2V0LGxlbmd0aA0KICAgICAgICAgIC8vIGdJbkJ1ZmZlclsyMl0gaXMgb2Zmc2V0IHN0cmluZywgKytQdHIgaXMgbGVuZ3RoIHN0cmluZ5INCiAgICAgICAgICBmb3IgKFB0ciA9ICZnSW5CdWZmZXJbMjJdOyAqUHRyICE9ICcsJzsgUHRyKyspOw0KDQogICAgICAgICAgLy8gTm90IHN1cmUgaWYgbXVsdGktcmFkaXggc3VwcG9ydCBpcyByZXF1aXJlZC4gQ3VycmVudGx5IG9ubHkgc3VwcG9ydCBkZWNpbWFsDQogICAgICAgICAgUXhmZXJMaWJyYXJ5IChBc2NpaVN0ckhleFRvVWludG4gKCZnSW5CdWZmZXJbMjJdKSwgQXNjaWlTdHJIZXhUb1VpbnRuICgrK1B0cikpOw0KICAgICAgICB9IGVsc2UgaWYgKEFzY2lpU3RybkNtcCAoZ0luQnVmZmVyLCAicU9mZnNldHMiLCA4KSA9PSAwKSB7DQogICAgICAgICAgQXNjaWlTUHJpbnQgKGdPdXRCdWZmZXIsIE1BWF9CVUZfU0laRSwgIlRleHQ9MTAwMDtEYXRhPWYwMDA7QnNzPWYwMDAiKTsNCiAgICAgICAgICBTZW5kUGFja2V0IChnT3V0QnVmZmVyKTsNCiAgICAgICAgfSBlbHNlIGlmIChBc2NpaVN0cm5DbXAgKGdJbkJ1ZmZlciwgInFBdHRhY2hlZCIsIDkpID09IDApIHsNCiAgICAgICAgICAvLyByZW1vdGUgc2VydmVyIGF0dGFjaGVkIHRvIGFuIGV4aXN0aW5nIHByb2Nlc3MNCiAgICAgICAgICBTZW5kUGFja2V0ICgiMSIpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIC8vU2VuZCBlbXB0eSBwYWNrZXQNCiAgICAgICAgICBTZW5kTm90U3VwcG9ydGVkICgpOw0KICAgICAgICB9DQogICAgICAgIGJyZWFrOw0KDQogICAgICBjYXNlICdzJzoNCiAgICAgICAgU2luZ2xlU3RlcCAoU3lzdGVtQ29udGV4dCwgZ0luQnVmZmVyKTsNCiAgICAgICAgcmV0dXJuOw0KDQogICAgICBjYXNlICd6JzoNCiAgICAgICAgUmVtb3ZlQnJlYWtQb2ludCAoU3lzdGVtQ29udGV4dCwgZ0luQnVmZmVyKTsNCiAgICAgICAgYnJlYWs7DQoNCiAgICAgIGNhc2UgJ1onOg0KICAgICAgICBJbnNlcnRCcmVha1BvaW50IChTeXN0ZW1Db250ZXh0LCBnSW5CdWZmZXIpOw0KICAgICAgICBicmVhazsNCg0KICAgICAgZGVmYXVsdDoNCiAgICAgICAgLy9TZW5kIGVtcHR5IHBhY2tldA0KICAgICAgICBTZW5kTm90U3VwcG9ydGVkICgpOw0KICAgICAgICBicmVhazsNCiAgICB9DQogIH0NCn0NCg0KDQoNCg0KDQo=