LyoqIEBmaWxlDQogIERlYnVnIEFnZW50IGxpYnJhcnkgaW1wbGVtZW50aXRpb24gd2l0aCBlbXB0eSBmdW5jdGlvbnMuDQoNCiAgQ29weXJpZ2h0IChjKSAyMDEwLCBJbnRlbCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC48QlI+DQogIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMNCiAgYXJlIGxpY2Vuc2VkIGFuZCBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIEJTRCBMaWNlbnNlDQogIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLiAgVGhlIGZ1bGwgdGV4dCBvZiB0aGUgbGljZW5zZSBtYXkgYmUgZm91bmQgYXQNCiAgaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL2JzZC1saWNlbnNlLnBocA0KDQogIFRIRSBQUk9HUkFNIElTIERJU1RSSUJVVEVEIFVOREVSIFRIRSBCU0QgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLA0KICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgUkVQUkVTRU5UQVRJT05TIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELg0KDQoqKi8NCg0KI2luY2x1ZGUgIkdkYkRlYnVnQWdlbnQuaCINCg0KDQpVSU5UTiAgICAgZ01heFByb2Nlc3NvckluZGV4ID0gMDsNCg0KLy8NCi8vIEJ1ZmZlcnMgZm9yIGJhc2ljIGdkYiBjb21tdW5pY2F0aW9uDQovLw0KQ0hBUjggZ0luQnVmZmVyW01BWF9CVUZfU0laRV07DQpDSEFSOCBnT3V0QnVmZmVyW01BWF9CVUZfU0laRV07DQoNCg0KLy8NCi8vIEdsb2JhbHMgZm9yIHJldHVybmluZyBYTUwgZnJvbSBxWGZlcjpsaWJyYXJpZXM6cmVhZCBwYWNrZXQNCi8vDQpVSU5UTiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ1BhY2tldHFYZmVyTGlicmFyeU9mZnNldCA9IDA7DQpVSU5UTiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ0VmaURlYnVnSW1hZ2VUYWJsZUVudHJ5ID0gMDsNCkNIQVI4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnWGZlckxpYnJhcnlCdWZmZXJbMjAwMF07DQoNCkdMT0JBTF9SRU1PVkVfSUZfVU5SRUZFUkVOQ0VEIENPTlNUIENIQVI4IG1IZXhUb1N0cltdID0geycwJywnMScsJzInLCczJywnNCcsJzUnLCc2JywnNycsJzgnLCc5JywnQScsJ0InLCdDJywnRCcsJ0UnLCdGJ307DQoNCg0KLy8gYWRkLXN5bWJvbC1maWxlIGM6L3dvcmsvZWRrMi9CdWlsZC9CZWFnbGVCb2FyZC9ERUJVR19BUk1HQ0MvQVJNL0JlYWdsZUJvYXJkUGtnL1NlYy9TZWMvREVCVUcvQmVhZ2xlQm9hcmRTZWMuZGxsIDB4ODAwMDgzNjAgDQpDSEFSOCAgKnFYZmVySGFjayA9ICI8bGlicmFyeSBuYW1lPVwiYzovd29yay9lZGsyL0J1aWxkL0JlYWdsZUJvYXJkL0RFQlVHX0FSTUdDQy9BUk0vQmVhZ2xlQm9hcmRQa2cvU2VjL1NlYy9ERUJVRy9CZWFnbGVCb2FyZFNlYy5kbGxcIj48c2VnbWVudCBhZGRyZXNzPVwiMHg4MDAwODM2MFwiLz48L2xpYnJhcnk+IjsNCg0KVUlOVE4NCmdYZmVyT2JqZWN0UmVhZFJlc3BvbnNlICgNCiAgSU4gIENIQVI4ICAgICAgICAgVHlwZSwNCiAgSU4gIENIQVI4ICAgICAgICAgKlN0cg0KICApDQp7DQogIENIQVI4ICAgKk91dEJ1ZlB0cjsgICAgICAgICAgICAgLy8gcG9pbnRlciB0byB0aGUgb3V0cHV0IGJ1ZmZlcg0KICBDSEFSOCAgIENoYXI7DQogIFVJTlROICAgQ291bnQ7DQoNCiAgLy8gcmVzcG9uY2Ugc3RhcnRzIHdpdGggJ20nIG9yICdsJyBpZiBpdCBpcyB0aGUgZW5kDQogIE91dEJ1ZlB0ciA9IGdPdXRCdWZmZXI7DQogICpPdXRCdWZQdHIrKyA9IFR5cGU7DQogIENvdW50ID0gMTsNCg0KICAvLyBCaW5hcnkgZGF0YSBlbmNvZGluZyANCiAgT3V0QnVmUHRyID0gZ091dEJ1ZmZlcjsNCiAgd2hpbGUgKCpTdHIgIT0gJ1wwJykgew0KICAgIENoYXIgPSAqU3RyKys7DQogICAgaWYgKChDaGFyID09IDB4N2QpIHx8IChDaGFyID09IDB4MjMpIHx8IChDaGFyID09IDB4MjQpIHx8IChDaGFyID09IDB4MmEpKSB7DQogICAgICAvLyBlc2NhcGUgY2hhcmFjdGVyDQogICAgICAqT3V0QnVmUHRyKysgPSAweDdkOw0KDQogICAgICBDaGFyIF49IDB4MjA7DQogICAgfQ0KICAgICpPdXRCdWZQdHIrKyA9IENoYXI7DQogICAgQ291bnQrKzsNCiAgfQ0KDQogICpPdXRCdWZQdHIgPSAnXDAnIDsgIC8vIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlcg0KICBTZW5kUGFja2V0IChnT3V0QnVmZmVyKTsNCiAgDQogIHJldHVybiBDb3VudDsNCn0NCg0KLyoqIA0KICBQcm9jZXNzICJxWGZlcjpvYmplY3Q6cmVhZDphbm5leDpvZmZzZXQsbGVuZ3RoIiByZXF1ZXN0Lg0KICANCiAgUmV0dXJucyBhbiBYTUwgZG9jdW1lbnQgdGhhdCBjb250YWlucyBsb2FkZWQgbGlicmFyaWVzLiBJbiBvdXIgY2FzZSBpdCBpcyANCiAgaW5mb21yYXRpb24gaW4gdGhlIEVGSSBEZWJ1ZyBJbm1hZ2UgVGFibGUgY29udmVydGVkIGludG8gYW4gWE1MIGRvY3VtZW50Lg0KICANCiAgR0RCIHdpbGwgY2FsbCB3aXRoIGFuIGFyYml0cmFyeSBsZW5ndGggKGl0IGNhbid0IGtub3cgdGhlIHJlYWwgbGVuZ3RoIGFuZCANCiAgd2lsbCByZXBseSB3aXRoIGNodW5rcyBvZiBYTUwgdGhhdCBhcmUgZWFzeSBmb3IgdXMgdG8gZGVhbCB3aXRoLiBHZGIgd2lsbCANCiAga2VlcCBjYWxsaW5nIHVudGlsIHdlIHNheSB3ZSBhcmUgZG9uZS4gWE1MIGRvYyBsb29rcyBsaWtlOg0KICANCiAgPGxpYnJhcnktbGlzdD4NCiAgICA8bGlicmFyeSBuYW1lPSIvYS9hL2MvZC5kU1lNIj48c2VnbWVudCBhZGRyZXNzPSIweDEwMDAwMDAwIi8+PC9saWJyYXJ5Pg0KICAgIDxsaWJyYXJ5IG5hbWU9Ii9hL20vZS9lLnBkYiI+PHNlZ21lbnQgYWRkcmVzcz0iMHgyMDAwMDAwMCIvPjwvbGlicmFyeT4NCiAgICA8bGlicmFyeSBuYW1lPSIvYS9sL2YvZi5kbGwiPjxzZWdtZW50IGFkZHJlc3M9IjB4MzAwMDAwMDAiLz48L2xpYnJhcnk+DQogIDwvbGlicmFyeS1saXN0Pg0KICANCiAgU2luY2Ugd2UgY2FuIG5vdCBhbGxvY2F0ZSBtZW1vcnkgaW4gaW50ZXJ1cHQgY29udGV4dCB0aGlzIG1vZHVsZSBoYXMgDQogIGFzc3VtcHRpb25zIGFib3V0IGhvdyBpdCB3aWxsIGdldCBjYWxsZWQ6DQogIDEpIExlbmd0aCB3aWxsIGdlbmVyYWxseSBiZSBtYXggcmVtb3RlIHBhY2tldCBzaXplIChiaWcgZW5vdWdoKQ0KICAyKSBGaXJzdCBPZmZzZXQgb2YgYW4gWE1MIGRvY3VtZW50IHJlYWQgbmVlZHMgdG8gYmUgMA0KICAzKSBUaGlzIGNvZGUgd2lsbCByZXR1cm4gYmFjayBzbWFsbCBjaHVua3Mgb2YgdGhlIFhNTCBkb2N1bWVudCBvbiBldmVyeSByZWFkLg0KICAgICBFYWNoIHN1YnNlcWVudCBjYWxsIHdpbGwgYXNrIGZvciB0aGUgbmV4dCBhdmFpbGJsZSBwYXJ0IG9mIHRoZSBkb2N1bWVudC4NCiAgICAgDQogIE5vdGU6IFRoZSBvbmx5IHZhcmlhYmxlIHNpemUgZWxlbWVudCBpbiB0aGUgWE1MIGlzOg0KICAiICA8bGlicmFyeSBuYW1lPVwiJXNcIj48c2VnbWVudCBhZGRyZXNzPVwiJXBcIi8+PC9saWJyYXJ5PlxuIiBhbmQgaXQgaXMgDQogIGJhc2VkIG9uIHRoZSBmaWxlIHBhdGggYW5kIG5hbWUgb2YgdGhlIHN5bWJvbCBmaWxlLiBJZiB0aGUgc3ltYm9sIGZpbGUgbmFtZQ0KICBpcyBiaWdnZXIgdGhhbiB0aGUgbWF4IGdkYiByZW1vdGUgcGFja2V0IHNpemUgd2UgY291bGQgdXBkYXRlIHRoaXMgY29kZQ0KICB0byByZXNwb25kIGJhY2sgaW4gY2h1bmtzLg0KDQogQHBhcmFtIE9mZnNldCAgb2Zmc2V0IGludG8gc3BlY2lhbCBkYXRhIGFyZWENCiBAcGFyYW0gTGVuZ3RoICBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZCBzdGFydGluZyBhdCBPZmZzZXQgIA0KICANCiAqKi8NClZPSUQNClF4ZmVyTGlicmFyeSAoDQogIElOICBVSU5UTiAgIE9mZnNldCwNCiAgSU4gIFVJTlROICAgTGVuZ3RoDQogICkNCnsNCiAgZ1BhY2tldHFYZmVyTGlicmFyeU9mZnNldCArPSBnWGZlck9iamVjdFJlYWRSZXNwb25zZSAoJ20nLCAiPGxpYnJhcnktbGlzdD5cbiIpOw0KICBnUGFja2V0cVhmZXJMaWJyYXJ5T2Zmc2V0ICs9IGdYZmVyT2JqZWN0UmVhZFJlc3BvbnNlICgnbScsIHFYZmVySGFjayk7DQogIGdYZmVyT2JqZWN0UmVhZFJlc3BvbnNlICgnbCcsICI8L2xpYnJhcnktbGlzdD5cbiIpOw0KICBnUGFja2V0cVhmZXJMaWJyYXJ5T2Zmc2V0ID0gMDsNCn0NCg0KLyoqDQogVHJhbnNmZXIgbGVuZ3RoIGJ5dGVzIG9mIGlucHV0IGJ1ZmZlciwgc3RhcnRpbmcgYXQgQWRkcmVzcywgdG8gbWVtb3J5Lg0KDQogQHBhcmFtICAgICBsZW5ndGggICAgICAgICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHRoZSBieXRlcyB0byBiZSB0cmFuc2ZlcnJlZC93cml0dGVuDQogQHBhcmFtICAgICAqYWRkcmVzcyAgICAgICAgICAgICAgICB0aGUgc3RhcnQgYWRkcmVzcyBvZiB0aGUgdHJhbnNmZXJyaW5nL3dyaXRpbmcgdGhlIG1lbW9yeQ0KIEBwYXJhbSAgICAgKm5ld19kYXRhICAgICAgICAgICAgICAgdGhlIG5ldyBkYXRhIHRvIGJlIHdyaXR0ZW4gdG8gbWVtb3J5DQogKiovDQoNClZPSUQNClRyYW5zZmVyRnJvbUluQnVmVG9NZW0gKA0KICBJTiAgICBVSU5UTiAgICAgICAgICAgICAgICAgICAgICAgTGVuZ3RoLA0KICBJTiAgICB1bnNpZ25lZCBjaGFyICAgICAgICAgICAgICAgKkFkZHJlc3MsDQogIElOICAgIENIQVI4ICAgICAgICAgICAgICAgICAgICAgICAqTmV3RGF0YQ0KICApDQp7DQogIENIQVI4IGMxOw0KICBDSEFSOCBjMjsNCiAgIA0KICB3aGlsZSAoTGVuZ3RoLS0gPiAwKSB7DQogICAgYzEgPSAoQ0hBUjgpSGV4Q2hhclRvSW50ICgqTmV3RGF0YSsrKTsNCiAgICBjMiA9IChDSEFSOClIZXhDaGFyVG9JbnQgKCpOZXdEYXRhKyspOw0KDQogICAgaWYgKChjMSA8IDApIHx8IChjMiA8IDApKSB7DQogICAgICBTZW5kRXJyb3IgKEdEQl9FQkFETUVNREFUQSk7IA0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgICAqQWRkcmVzcysrID0gKFVJTlQ4KSgoYzEgPDwgNCkgKyBjMik7DQogIH0NCg0KICBTZW5kU3VjY2VzcygpOw0KfQ0KDQoNCi8qKg0KIFRyYW5zZmVyIExlbmd0aCBieXRlcyBvZiBtZW1vcnkgc3RhcnRpbmcgYXQgQWRkcmVzcyB0byBhbiBvdXRwdXQgYnVmZmVyLCBPdXRCdWZmZXIuIFRoaXMgZnVuY3Rpb24gd2lsbCBmaW5hbGx5IHNlbmQgdGhlIGJ1ZmZlcg0KIGFzIGEgcGFja2V0Lg0KDQogQHBhcmFtICAgICBMZW5ndGggICAgICAgICAgICAgICAgICB0aGUgbnVtYmVyIG9mIHRoZSBieXRlcyB0byBiZSB0cmFuc2ZlcnJlZC9yZWFkDQogQHBhcmFtICAgICAqYWRkcmVzcyAgICAgICAgICAgICAgICBwb2ludGVyIHRvIHRoZSBzdGFydCBhZGRyZXNzIG9mIHRoZSB0cmFuc2ZlcnJpbmcvcmVhZGluZyB0aGUgbWVtb3J5DQogKiovDQoNClZPSUQNClRyYW5zZmVyRnJvbU1lbVRvT3V0QnVmQW5kU2VuZCAoDQogIElOICAgIFVJTlROICAgICAgICAgICAgICAgICAgICAgICBMZW5ndGgsDQogIElOICAgIHVuc2lnbmVkIGNoYXIgICAgICAgICAgICAgICAqQWRkcmVzcw0KICApDQp7DQogIC8vIHRoZXJlIGFyZSBMZW5ndGggYnl0ZXMgYW5kIGV2ZXJ5IGJ5dGUgaXMgcmVwcmVzZW50ZWQgYXMgMiBoZXggY2hhcnMNCiAgQ0hBUjggICBPdXRCdWZmZXJbTUFYX0JVRl9TSVpFXTsNCiAgQ0hBUjggICAqT3V0QnVmUHRyOyAgICAgICAgICAgICAvLyBwb2ludGVyIHRvIHRoZSBvdXRwdXQgYnVmZmVyDQogIENIQVI4ICAgQ2hhcjsNCg0KICBPdXRCdWZQdHIgPSBPdXRCdWZmZXI7DQogIHdoaWxlIChMZW5ndGggPiAwKSB7DQogICAgDQogICAgQ2hhciA9IG1IZXhUb1N0clsqQWRkcmVzcyA+PiA0XTsNCiAgICBpZiAoKENoYXIgPj0gJ0EnKSAmJiAoQ2hhciA8PSAnRicpKSB7DQogICAgICBDaGFyID0gQ2hhciAtICdBJyArICdhJzsNCiAgICB9DQogICAgKk91dEJ1ZlB0cisrID0gQ2hhcjsNCg0KICAgIENoYXIgPSBtSGV4VG9TdHJbKkFkZHJlc3MgJiAweDBmXTsNCiAgICBpZiAoKENoYXIgPj0gJ0EnKSAmJiAoQ2hhciA8PSAnRicpKSB7DQogICAgICBDaGFyID0gQ2hhciAtICdBJyArICdhJzsNCiAgICB9DQogICAgKk91dEJ1ZlB0cisrID0gQ2hhcjsNCg0KICAgIEFkZHJlc3MrKzsNCiAgICBMZW5ndGgtLTsNCiAgfQ0KDQogICpPdXRCdWZQdHIgPSAnXDAnIDsgIC8vIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlcg0KICBTZW5kUGFja2V0IChPdXRCdWZmZXIpOw0KfQ0KDQoNCg0KLyoqDQogIFNlbmQgYSBHREIgUmVtb3RlIFNlcmlhbCBQcm90b2NvbCBQYWNrZXQNCiAgDQogICRQYWNrZXREYXRhI2NoZWNrc3VtIFBhY2tldERhdGEgaXMgcGFzc2VkIGluIGFuZCB0aGlzIGZ1bmN0aW9uIGFkZHMgdGhlIHBhY2tldCBwcmVmaXggJyQnLCANCiAgdGhlIHBhY2tldCB0ZW1pbmF0aW5nIGNoYXJhY3RlciAnIycgYW5kIHRoZSB0d28gZGlnaXQgY2hlY2tzdW0uDQogIA0KICBJZiBhbiBhY2sgJysnIGlzIG5vdCBzZW50IHJlc2VuZCB0aGUgcGFja2V0LCBidXQgdGltZW91dCBldmVudHVhbGx5IHNvIHdlIGRvbid0IGVuZCB1cCANCiAgaW4gYW4gaW5maW5pdCBsb29wLiBUaGlzIGlzIHNvIGlmIHlvdSB1bnBsdWcgdGhlIGRlYnVnZ2VyIGNvZGUganVzdCBrZWVwcyBydW5uaW5nDQoNCiAgQHBhcmFtIFBhY2tldERhdGEgICBQYXlsb2FkIGRhdGEgZm9yIHRoZSBwYWNrZXQgIA0KDQogIA0KICBAcmV0dmFsICAgICAgICAgICAgIE51bWJlciBvZiBieXRlcyBvZiBwYWNrZXQgZGF0YSBzZW50Lg0KDQoqKi8NClVJTlRODQpTZW5kUGFja2V0ICgNCiAgSU4gIENIQVI4ICpQYWNrZXREYXRhDQogICkNCnsNCiAgVUlOVDggQ2hlY2tTdW07DQogIFVJTlROIFRpbWVvdXQ7DQogIENIQVI4ICpQdHI7DQogIENIQVI4IFRlc3RDaGFyOw0KICBVSU5UTiBDb3VudDsNCiAgDQogIFRpbWVvdXQgPSBQY2RHZXQzMiAoUGNkR2RiTWF4UGFja2V0UmV0cnlDb3VudCk7DQoNCiAgQ291bnQgPSAwOw0KICBkbyB7DQoNCiAgICBQdHIgPSBQYWNrZXREYXRhOw0KDQogICAgaWYgKFRpbWVvdXQtLSA9PSAwKSB7DQogICAgICAvLyBPbmx5IHRyeSBhIGZpbml0ZSBudW1iZXIgb2YgdGltZXMgc28gd2UgZG9uJ3QgZ2V0IHN0dWNrIGluIHRoZSBsb29wDQogICAgICByZXR1cm4gQ291bnQ7DQogICAgfQ0KICANCiAgICAvLyBQYWNrZXQgcHJlZml4DQogICAgR2RiUHV0Q2hhciAoJyQnKTsNCiAgDQogICAgZm9yIChDaGVja1N1bSA9IDAsIENvdW50ID0wIDsgKlB0ciAhPSAnXDAnOyBQdHIrKywgQ291bnQrKykgew0KICAgICAgR2RiUHV0Q2hhciAoKlB0cik7DQogICAgICBDaGVja1N1bSA9IENoZWNrU3VtICsgKlB0cjsNCiAgICB9DQogIA0KICAgIC8vIFBhY2tldCB0ZXJtaW5hdGluZyBjaGFyYWN0ZXIgYW5kIGNoZWNrc3VtIA0KICAgIEdkYlB1dENoYXIgKCcjJyk7DQogICAgR2RiUHV0Q2hhciAobUhleFRvU3RyW0NoZWNrU3VtID4+IDRdKTsNCiAgICBHZGJQdXRDaGFyIChtSGV4VG9TdHJbQ2hlY2tTdW0gJiAweDBGXSk7DQogICAgDQogICAgVGVzdENoYXIgPSAgR2RiR2V0Q2hhciAoKTsNCiAgfSB3aGlsZSAoVGVzdENoYXIgIT0gJysnKTsNCiAgDQogIHJldHVybiBDb3VudDsNCn0NCg0KLyoqDQogIFJlY2VpdmUgYSBHREIgUmVtb3RlIFNlcmlhbCBQcm90b2NvbCBQYWNrZXQNCiAgDQogICRQYWNrZXREYXRhI2NoZWNrc3VtIFBhY2tldERhdGEgaXMgcGFzc2VkIGluIGFuZCB0aGlzIGZ1bmN0aW9uIGFkZHMgdGhlIHBhY2tldCBwcmVmaXggJyQnLCANCiAgdGhlIHBhY2tldCB0ZW1pbmF0aW5nIGNoYXJhY3RlciAnIycgYW5kIHRoZSB0d28gZGlnaXQgY2hlY2tzdW0uDQogDQogIElmIGhvc3QgcmUtc3RhcnRzIHNlbmRpbmcgYSBwYWNrZXQgd2l0aG91dCBlbmRpbmcgdGhlIHByZXZpb3VzIHBhY2tldCwgb25seSB0aGUgbGFzdCB2YWxpZCBwYWNrZXQgaXMgcHJvY2Nlc3NlZC4NCiAgKEluIG90aGVyIHdvcmRzLCBpZiByZWNlaXZlZCBwYWNrZXQgaXMgJyQxMjM0NSQxMjM0NSQxMjM0NTYjY2hlY2tzdW0nLCBvbmx5ICckMTIzNDU2I2NoZWNrc3VtJyB3aWxsIGJlIHByb2Nlc3NlZC4pDQogDQogIElmIGFuIGFjayAnKycgaXMgbm90IHNlbnQgcmVzZW5kIHRoZSBwYWNrZXQNCg0KICBAcGFyYW0gUGFja2V0RGF0YSAgIFBheWxvYWQgZGF0YSBmb3IgdGhlIHBhY2tldCAgDQoNCiAgQHJldHZhbCAgICAgICAgICAgICBOdW1iZXIgb2YgYnl0ZXMgb2YgcGFja2V0IGRhdGEgcmVjZWl2ZWQuDQoNCioqLw0KVUlOVE4NClJlY2VpdmVQYWNrZXQgKA0KICBPVVQgIENIQVI4ICpQYWNrZXREYXRhLA0KICBJTiAgIFVJTlROIFBhY2tldERhdGFTaXplDQogKQ0Kew0KICBVSU5UOCBDaGVja1N1bTsNCiAgVUlOVE4gSW5kZXg7DQogIENIQVI4IENoYXI7DQogIENIQVI4IFN1bVN0cmluZ1szXTsNCiAgQ0hBUjggVGVzdENoYXI7DQogIA0KICBaZXJvTWVtIChQYWNrZXREYXRhLCBQYWNrZXREYXRhU2l6ZSk7DQogIA0KICBmb3IgKDs7KSB7DQogICAgICAvLyB3YWl0IGZvciB0aGUgc3RhcnQgb2YgYSBwYWNrZXQNCiAgICBUZXN0Q2hhciA9IEdkYkdldENoYXIgKCk7DQogICAgd2hpbGUgKFRlc3RDaGFyICE9ICckJykgew0KICAgICAgVGVzdENoYXIgPSBHZGJHZXRDaGFyICgpOw0KICAgIH07DQogICAgDQogIHJldHJ5Og0KICAgIGZvciAoSW5kZXggPSAwLCBDaGVja1N1bSA9IDA7IEluZGV4IDwgKFBhY2tldERhdGFTaXplIC0gMSk7IEluZGV4KyspIHsNCiAgICAgIENoYXIgPSBHZGJHZXRDaGFyICgpOw0KICAgICAgaWYgKENoYXIgPT0gJyQnKSB7DQogICAgICAgIGdvdG8gcmV0cnk7DQogICAgICB9DQogICAgICBpZiAoQ2hhciA9PSAnIycpIHsNCiAgICAgICAgYnJlYWs7DQogICAgICB9DQoNCiAgICAgIFBhY2tldERhdGFbSW5kZXhdID0gQ2hhcjsNCiAgICAgIENoZWNrU3VtID0gQ2hlY2tTdW0gKyBDaGFyOw0KICAgIH0NCiAgICBQYWNrZXREYXRhW0luZGV4XSA9ICdcMCc7DQoNCiAgICBpZiAoSW5kZXggPT0gUGFja2V0RGF0YVNpemUpIHsNCiAgICAgIGNvbnRpbnVlOw0KICAgIH0NCg0KICAgIFN1bVN0cmluZ1swXSA9IEdkYkdldENoYXIgKCk7ICANCiAgICBTdW1TdHJpbmdbMV0gPSBHZGJHZXRDaGFyICgpOw0KICAgIFN1bVN0cmluZ1syXSA9ICdcMCc7DQogICAgDQogICAgaWYgKEFzY2lpU3RySGV4VG9VaW50biAoU3VtU3RyaW5nKSA9PSBDaGVja1N1bSkgew0KICAgICAgLy8gQWNrOiBTdWNjZXNzDQogICAgICBHZGJQdXRDaGFyICgnKycpOw0KICANCiAgICAgIC8vIE51bGwgdGVybWluYXRlIHRoZSBjYWxsZXJzIHN0cmluZw0KICAgICAgUGFja2V0RGF0YVtJbmRleF0gPSAnXDAnOw0KICAgICAgcmV0dXJuIEluZGV4Ow0KICAgIH0gZWxzZSB7DQogICAgICAvLyBBY2s6IEZhaWx1cmUNCiAgICAgIEdkYlB1dENoYXIgKCctJyk7DQogICAgfQ0KICB9DQogIA0KICAvL3JldHVybiAwOw0KfQ0KDQoNCi8qKg0KIEVtcHRpZXMgdGhlIGdpdmVuIGJ1ZmZlciANCiBAcGFyYW0gICBCdWYgICAgICAgICAgcG9pbnRlciB0byB0aGUgZmlyc3QgZWxlbWVudCBpbiBidWZmZXIgdG8gYmUgZW1wdGllZA0KICoqLw0KVk9JRA0KRW1wdHlCdWZmZXIgKCANCiAgSU4gIENIQVI4ICAgICAgICAgICAqQnVmDQogICkNCnsgDQogICpCdWYgPSAnXDAnOw0KfQ0KDQoNCi8qKg0KIENvbnZlcnRzIGFuIDgtYml0IEhleCBDaGFyIGludG8gYSBJTlROLg0KIA0KIEBwYXJhbSAgIENoYXIgdGhlIGhleCBjaGFyYWN0ZXIgdG8gYmUgY29udmVydGVkIGludG8gVUlOVE4NCiBAcmV0dmFsICBhIElOVE4sIGZyb20gMCB0byAxNSwgdGhhdCBjb3JyZXNzcG9uZHMgdG8gQ2hhcg0KIC0xIGlmIENoYXIgaXMgbm90IGEgaGV4IGNoYXJhY3Rlcg0KICoqLw0KSU5UTg0KSGV4Q2hhclRvSW50ICgNCiAgSU4gIENIQVI4ICAgICAgICAgICBDaGFyDQogICkNCnsNCiAgaWYgKChDaGFyID49ICdBJykgJiYgKENoYXIgPD0gJ0YnKSkgew0KICAgIHJldHVybiBDaGFyIC0gJ0EnICsgMTA7DQogIH0gZWxzZSBpZiAoKENoYXIgPj0gJ2EnKSAmJiAoQ2hhciA8PSAnZicpKSB7DQogICAgcmV0dXJuIENoYXIgLSAnYScgKyAxMDsNCiAgfSBlbHNlIGlmICgoQ2hhciA+PSAnMCcpICYmIChDaGFyIDw9ICc5JykpIHsNCiAgICByZXR1cm4gQ2hhciAtICcwJzsNCiAgfSBlbHNlIHsgLy8gaWYgbm90IGEgaGV4IHZhbHVlLCByZXR1cm4gYSBuZWdhdGl2ZSB2YWx1ZQ0KICAgIHJldHVybiAtMTsgDQogIH0NCn0NCg0KICAvLyAnRScgKyB0aGUgYmlnZ2VzdCBlcnJvciBudW1iZXIgaXMgMjU1LCBzbyBpdHMgMiBoZXggZGlnaXRzICsgYnVmZmVyIGVuZA0KQ0hBUjggKmdFcnJvciA9ICJFX18iOw0KDQovKiogJ0UgTk4nDQogU2VuZCBhbiBlcnJvciB3aXRoIHRoZSBnaXZlbiBlcnJvciBudW1iZXIgYWZ0ZXIgY29udmVydGluZyB0byBoZXguDQogVGhlIGVycm9yIG51bWJlciBpcyBwdXQgaW50byB0aGUgYnVmZmVyIGluIGhleC4gJzI1NScgaXMgdGhlIGJpZ2dlc3QgZXJybm8gd2UgY2FuIHNlbmQuDQogZXg6IDE2MiB3aWxsIGJlIHNlbnQgYXMgQTIuDQogDQogQHBhcmFtICAgZXJybm8gICAgICAgICAgIHRoZSBlcnJvciBudW1iZXIgdGhhdCB3aWxsIGJlIHNlbnQNCiAqKi8NClZPSUQNCkVGSUFQSQ0KU2VuZEVycm9yICgNCiAgSU4gIFVJTlQ4ICAgICAgICAgICAgICBFcnJvck51bQ0KICApDQp7DQogIC8vDQogIC8vIFJlcGxhY2UgXywgb3Igb2xkIGRhdGEsIHdpdGggY3VycmVudCBlcnJubw0KICAvLw0KICBnRXJyb3JbMV0gPSBtSGV4VG9TdHIgW0Vycm9yTnVtID4+IDRdOw0KICBnRXJyb3JbMl0gPSBtSGV4VG9TdHIgW0Vycm9yTnVtICYgMHgwZl07DQogICAgDQogIFNlbmRQYWNrZXQgKGdFcnJvcik7IC8vIHNlbmQgYnVmZmVyDQp9DQoNCg0KDQovKioNCiBTZW5kICdPSycgd2hlbiB0aGUgZnVuY3Rpb24gaXMgZG9uZSBleGVjdXRpbmcgc3VjY2Vzc2Z1bGx5Lg0KICoqLw0KVk9JRA0KRUZJQVBJDQpTZW5kU3VjY2VzcyAoDQogIFZPSUQNCiAgKSANCnsNCiAgU2VuZFBhY2tldCAoIk9LIik7IC8vIHNlbmQgYnVmZmVyDQp9DQoNCg0KLyoqDQogU2VuZCBlbXB0eSBwYWNrZXQgdG8gc3BlY2lmeSB0aGF0IHBhcnRpY3VsYXIgY29tbWFuZC9mdW5jdGlvbmFsaXR5IGlzIG5vdCBzdXBwb3J0ZWQuDQogKiovDQpWT0lEICAgICAgICANCkVGSUFQSSAgICAgIA0KU2VuZE5vdFN1cHBvcnRlZCAoDQogIFZPSUQgICAgICAgICAgDQogICkgICAgICAgICAgICAgDQp7ICAgICAgIA0KICBTZW5kUGFja2V0ICgiIik7DQp9DQoNCg0KDQoNCg0KLyoqDQogVHJhbnNsYXRlcyB0aGUgRUZJIG1hcHBpbmcgdG8gR0RCIG1hcHBpbmcNCiANCiBAcGFyYW0gICBFRklFeGNlcHRpb25UeXBlICAgIEVGSSBFeGNlcHRpb24gdGhhdCBpcyBiZWluZyBwcm9jZXNzZWQNCiBAcmV0dmFsICBVSU5UTiB0aGF0IGNvcnJlc3BvbmRzIHRvIEVGSUV4Y2VwdGlvblR5cGUncyBHREIgZXhjZXB0aW9uIHR5cGUgbnVtYmVyDQogKiovDQpVSU5UOA0KQ29udmVydEVGSXRvR0RCdHlwZSAoIA0KICBJTiAgRUZJX0VYQ0VQVElPTl9UWVBFICAgICAgRUZJRXhjZXB0aW9uVHlwZQ0KICApDQp7IA0KICBVSU5UTiBpOw0KICANCiAgZm9yIChpPTA7IGkgPCBNYXhFZmlFeGNlcHRpb24oKSA7IGkrKykgew0KICAgIGlmIChnRXhjZXB0aW9uVHlwZVtpXS5FeGNlcHRpb24gPT0gRUZJRXhjZXB0aW9uVHlwZSkgew0KICAgICAgcmV0dXJuIGdFeGNlcHRpb25UeXBlW2ldLlNpZ25hbE5vOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gR0RCX1NJR1RSQVA7IC8vIHRoaXMgaXMgYSBHREIgdHJhcA0KfQ0KDQoNCi8qKiAibSBhZGRyLGxlbmd0aCINCiBGaW5kIHRoZSBMZW5ndGggb2YgdGhlIGFyZWEgdG8gcmVhZCBhbmQgdGhlIHN0YXJ0IGFkZHJlcy4gRmluYWxseSwgcGFzcyB0aGVtIHRvIA0KIGFub3RoZXIgZnVuY3Rpb24sIFRyYW5zZmVyRnJvbU1lbVRvT3V0QnVmQW5kU2VuZCwgdGhhdCB3aWxsIHJlYWQgZnJvbSB0aGF0IG1lbW9yeSBzcGFjZSBhbmQgDQogc2VuZCBpdCBhcyBhIHBhY2tldC4NCiAqKi8NCg0KVk9JRA0KRUZJQVBJDQpSZWFkRnJvbU1lbW9yeSAoDQogIENIQVI4ICpQYWNrZXREYXRhDQogICkNCnsNCiAgVUlOVE4gQWRkcmVzczsNCiAgVUlOVE4gTGVuZ3RoOw0KICBDSEFSOCBBZGRyZXNzQnVmZmVyW01BWF9BRERSX1NJWkVdOyAvLyB0aGUgYnVmZmVyIHRoYXQgd2lsbCBob2xkIHRoZSBhZGRyZXNzIGluIGhleCBjaGFycw0KICBDSEFSOCAqQWRkckJ1ZlB0cjsgLy8gcG9pbnRlciB0byB0aGUgYWRkcmVzcyBidWZmZXINCiAgQ0hBUjggKkluQnVmUHRyOyAvLy8gcG9pbnRlciB0byB0aGUgaW5wdXQgYnVmZmVyDQogIA0KICBBZGRyQnVmUHRyID0gQWRkcmVzc0J1ZmZlcjsNCiAgSW5CdWZQdHIgPSAmUGFja2V0RGF0YVsxXTsNCiAgd2hpbGUgKCpJbkJ1ZlB0ciAhPSAnLCcpIHsNCiAgICAqQWRkckJ1ZlB0cisrID0gKkluQnVmUHRyKys7DQogIH0NCiAgKkFkZHJCdWZQdHIgPSAnXDAnOw0KICANCiAgSW5CdWZQdHIrKzsgLy8gdGhpcyBza2lwcyAnLCcgaW4gdGhlIGJ1ZmZlcg0KICANCiAgLyogRXJyb3IgY2hlY2tpbmcgKi8NCiAgaWYgKEFzY2lpU3RyTGVuKEFkZHJlc3NCdWZmZXIpID49IE1BWF9BRERSX1NJWkUpIHsNCiAgICBTZW5kRXJyb3IgKEdEQl9FQkFETUVNQUREUkJVRlNJWkUpOyANCiAgICByZXR1cm47DQogIH0NCiAgDQogIC8vIDIgPSAnbScgKyAnLCcNCiAgaWYgKEFzY2lpU3RyTGVuKFBhY2tldERhdGEpIC0gQXNjaWlTdHJMZW4oQWRkcmVzc0J1ZmZlcikgLSAyID49IE1BWF9MRU5HVEhfU0laRSkgew0KICAgIFNlbmRFcnJvciAoR0RCX0VCQURNRU1MRU5HVEgpOyANCiAgICByZXR1cm47DQogIH0NCiAgDQogIEFkZHJlc3MgPSBBc2NpaVN0ckhleFRvVWludG4gKEFkZHJlc3NCdWZmZXIpOw0KICBMZW5ndGggPSBBc2NpaVN0ckhleFRvVWludG4gKEluQnVmUHRyKTsNCiAgDQogIFRyYW5zZmVyRnJvbU1lbVRvT3V0QnVmQW5kU2VuZCAoTGVuZ3RoLCAodW5zaWduZWQgY2hhciAqKUFkZHJlc3MpOw0KfQ0KDQoNCi8qKiAiTSBhZGRyLGxlbmd0aCA6WFguLi4iDQogRmluZCB0aGUgTGVuZ3RoIG9mIHRoZSBhcmVhIGluIGJ5dGVzIHRvIHdyaXRlIGFuZCB0aGUgc3RhcnQgYWRkcmVzLiBGaW5hbGx5LCBwYXNzIHRoZW0gdG8gDQogYW5vdGhlciBmdW5jdGlvbiwgVHJhbnNmZXJGcm9tSW5CdWZUb01lbSwgdGhhdCB3aWxsIHdyaXRlIHRvIHRoYXQgbWVtb3J5IHNwYWNlIHRoZSBpbmZvIGluDQogdGhlIGlucHV0IGJ1ZmZlci4NCiAqKi8NClZPSUQNCkVGSUFQSQ0KV3JpdGVUb01lbW9yeSAoDQogIElOIENIQVI4ICpQYWNrZXREYXRhDQogICkNCnsNCiAgVUlOVE4gQWRkcmVzczsNCiAgVUlOVE4gTGVuZ3RoOw0KICBVSU5UTiBNZXNzYWdlTGVuZ3RoOw0KICBDSEFSOCBBZGRyZXNzQnVmZmVyW01BWF9BRERSX1NJWkVdOyAvLyB0aGUgYnVmZmVyIHRoYXQgd2lsbCBob2xkIHRoZSBBZGRyZXNzIGluIGhleCBjaGFycw0KICBDSEFSOCBMZW5ndGhCdWZmZXJbTUFYX0xFTkdUSF9TSVpFXTsgLy8gdGhlIGJ1ZmZlciB0aGF0IHdpbGwgaG9sZCB0aGUgTGVuZ3RoIGluIGhleCBjaGFycw0KICBDSEFSOCAqQWRkckJ1ZlB0cjsgLy8gcG9pbnRlciB0byB0aGUgQWRkcmVzcyBidWZmZXINCiAgQ0hBUjggKkxlbmd0aEJ1ZlB0cjsgLy8gcG9pbnRlciB0byB0aGUgTGVuZ3RoIGJ1ZmZlcg0KICBDSEFSOCAqSW5CdWZQdHI7IC8vLyBwb2ludGVyIHRvIHRoZSBpbnB1dCBidWZmZXINCiAgDQogIEFkZHJCdWZQdHIgPSBBZGRyZXNzQnVmZmVyOw0KICBMZW5ndGhCdWZQdHIgPSBMZW5ndGhCdWZmZXI7DQogIEluQnVmUHRyID0gJlBhY2tldERhdGFbMV07DQogIA0KICB3aGlsZSAoKkluQnVmUHRyICE9ICcsJykgew0KICAgICpBZGRyQnVmUHRyKysgPSAqSW5CdWZQdHIrKzsNCiAgfQ0KICAqQWRkckJ1ZlB0ciA9ICdcMCc7DQogIA0KICBJbkJ1ZlB0cisrOyAvLyB0aGlzIHNraXBzICcsJyBpbiB0aGUgYnVmZmVyDQogIA0KICB3aGlsZSAoKkluQnVmUHRyICE9ICc6Jykgew0KICAgICpMZW5ndGhCdWZQdHIrKyA9ICpJbkJ1ZlB0cisrOw0KICB9DQogICpMZW5ndGhCdWZQdHIgPSAnXDAnOw0KICANCiAgSW5CdWZQdHIrKzsgLy8gdGhpcyBza2lwcyAnOicgaW4gdGhlIGJ1ZmZlcg0KICANCiAgQWRkcmVzcyA9IEFzY2lpU3RySGV4VG9VaW50biAoQWRkcmVzc0J1ZmZlcik7DQogIExlbmd0aCA9IEFzY2lpU3RySGV4VG9VaW50biAoTGVuZ3RoQnVmZmVyKTsNCiAgDQogIC8qIEVycm9yIGNoZWNraW5nICovDQogIA0KICAvL0NoZWNrIGlmIEFkZHJlc3MgaXMgbm90IHRvbyBsb25nLg0KICBpZiAoQXNjaWlTdHJMZW4oQWRkcmVzc0J1ZmZlcikgPj0gTUFYX0FERFJfU0laRSkgew0KICAgIFNlbmRFcnJvciAoR0RCX0VCQURNRU1BRERSQlVGU0laRSk7IA0KICAgIHJldHVybjsNCiAgfQ0KICANCiAgLy9DaGVjayBpZiBtZXNzYWdlIGxlbmd0aCBpcyBub3QgdG9vIGxvbmcNCiAgaWYgKEFzY2lpU3RyTGVuKExlbmd0aEJ1ZmZlcikgPj0gTUFYX0xFTkdUSF9TSVpFKSB7DQogICAgU2VuZEVycm9yIChHREJfRUJBRE1FTUxFTkdCVUZTSVpFKTsgDQogICAgcmV0dXJuOw0KICB9DQogIA0KICAvLyBDaGVjayBpZiBNZXNzYWdlIGlzIG5vdCB0b28gbG9uZy9zaG9ydC4NCiAgLy8gMyA9ICdNJyArICcsJyArICc6Jw0KICBNZXNzYWdlTGVuZ3RoID0gKEFzY2lpU3RyTGVuKFBhY2tldERhdGEpIC0gQXNjaWlTdHJMZW4oQWRkcmVzc0J1ZmZlcikgLSBBc2NpaVN0ckxlbihMZW5ndGhCdWZmZXIpIC0gMyk7DQogIGlmIChNZXNzYWdlTGVuZ3RoICE9ICgyKkxlbmd0aCkpIHsNCiAgICAvL01lc3NhZ2UgdG9vIGxvbmcvc2hvcnQuIE5ldyBkYXRhIGlzIG5vdCB0aGUgcmlnaHQgc2l6ZS4NCiAgICBTZW5kRXJyb3IgKEdEQl9FQkFETUVNREFUQVNJWkUpOyAgIA0KICAgIHJldHVybjsNCiAgfQ0KICBUcmFuc2ZlckZyb21JbkJ1ZlRvTWVtIChMZW5ndGgsICh1bnNpZ25lZCBjaGFyICopQWRkcmVzcywgSW5CdWZQdHIpOw0KfQ0KDQovKioNCiAgUGFyc2VzIGJyZWFrcG9pbnQgcGFja2V0IGRhdGEgYW5kIGNhcHR1cmVzIEJyZWFrcG9pbnQgdHlwZSwgQWRkcmVzcyBhbmQgbGVuZ3RoLg0KICBJbiBjYXNlIG9mIGFuIGVycm9yLCBmdW5jdGlvbiByZXR1cm5zIHBhcnRpY3VsYXIgZXJyb3IgY29kZS4gUmV0dXJuaW5nIDAgbWVhbmluZw0KICBubyBlcnJvci4NCg0KICBAcGFyYW0gIFBhY2tldERhdGEgIFBvaW50ZXIgdG8gdGhlIHBheWxvYWQgZGF0YSBmb3IgdGhlIHBhY2tldC4NCiAgQHBhcmFtICBUeXBlICAgICAgICBCcmVha3BvaW50IHR5cGUNCiAgQHBhcmFtICBBZGRyZXNzICAgICBCcmVha3BvaW50IGFkZHJlc3MNCiAgQHBhcmFtICBMZW5ndGggICAgICBCcmVha3BvaW50IGxlbmd0aCBpbiBCeXRlcyAoMSBieXRlLCAyIGJ5dGUsIDQgYnl0ZSkNCg0KICBAcmV0dmFsIDEgICAgICAgICAgIFN1Y2Nlc3MNCiAgQHJldHZhbCB7b3RoZXJ9ICAgICBQYXJ0aWN1bGFyIGVycm9yIGNvZGUNCg0KKiovDQpVSU5UTg0KUGFyc2VCcmVha3BvaW50UGFja2V0ICgNCiAgSU4gIENIQVI4ICpQYWNrZXREYXRhLA0KICBPVVQgVUlOVE4gKlR5cGUsDQogIE9VVCBVSU5UTiAqQWRkcmVzcywNCiAgT1VUIFVJTlROICpMZW5ndGgNCiAgKQ0Kew0KICBDSEFSOCBBZGRyZXNzQnVmZmVyW01BWF9BRERSX1NJWkVdOw0KICBDSEFSOCAqQWRkcmVzc0J1ZmZlclB0cjsNCiAgQ0hBUjggKlBhY2tldERhdGFQdHI7DQoNCiAgUGFja2V0RGF0YVB0ciA9ICZQYWNrZXREYXRhWzFdOw0KICBBZGRyZXNzQnVmZmVyUHRyID0gQWRkcmVzc0J1ZmZlcjsNCg0KICAqVHlwZSA9IEFzY2lpU3RySGV4VG9VaW50biAoUGFja2V0RGF0YVB0cik7DQoNCiAgLy9CcmVha3BvaW50L3dhdGNocG9pbnQgdHlwZSBzaG91bGQgYmUgYmV0d2VlbiAwIHRvIDQNCiAgaWYgKCpUeXBlID4gNCkgew0KICAgIHJldHVybiAyMjsgLy9FSU5WQUw6IEludmFsaWQgYXJndW1lbnQuDQogIH0NCg0KICAvL1NraXAgJywnIGluIHRoZSBidWZmZXIuDQogIHdoaWxlICgqUGFja2V0RGF0YVB0cisrICE9ICcsJyk7DQoNCiAgLy9QYXJzZSBBZGRyZXNzIGluZm9ybWF0aW9uDQogIHdoaWxlICgqUGFja2V0RGF0YVB0ciAhPSAnLCcpIHsNCiAgICAqQWRkcmVzc0J1ZmZlclB0cisrID0gKlBhY2tldERhdGFQdHIrKzsNCiAgfQ0KICAqQWRkcmVzc0J1ZmZlclB0ciA9ICdcMCc7DQoNCiAgLy9DaGVjayBpZiBBZGRyZXNzIGlzIG5vdCB0b28gbG9uZy4NCiAgaWYgKEFzY2lpU3RyTGVuKEFkZHJlc3NCdWZmZXIpID49IE1BWF9BRERSX1NJWkUpIHsNCiAgICByZXR1cm4gNDA7IC8vRU1TR1NJWkU6IE1lc3NhZ2Ugc2l6ZSB0b28gbG9uZy4NCiAgfQ0KDQogICpBZGRyZXNzID0gQXNjaWlTdHJIZXhUb1VpbnRuIChBZGRyZXNzQnVmZmVyKTsNCg0KICBQYWNrZXREYXRhUHRyKys7IC8vVGhpcyBza2lwcyAsIGluIHRoZSBidWZmZXINCg0KICAvL1BhcnNlIExlbmd0aCBpbmZvcm1hdGlvbg0KICAqTGVuZ3RoID0gQXNjaWlTdHJIZXhUb1VpbnRuIChQYWNrZXREYXRhUHRyKTsNCg0KICAvL0xlbmd0aCBzaG91bGQgYmUgMSwgMiBvciA0IGJ5dGVzDQogIGlmICgqTGVuZ3RoID4gNCkgew0KICAgIHJldHVybiAyMjsgLy9FSU5WQUw6IEludmFsaWQgYXJndW1lbnQNCiAgfQ0KDQogIHJldHVybiAwOyAvLzAgPSBObyBlcnJvcg0KfQ0KDQoNCg0KLyoqDQogU2VuZCB0aGUgVCBzaWduYWwgd2l0aCB0aGUgZ2l2ZW4gZXhjZXB0aW9uIHR5cGUgKGluIGdkYiBvcmRlcikgYW5kIHBvc3NpYmx5IHdpdGggbjpyIHBhaXJzIHJlbGF0ZWQgdG8gdGhlIHdhdGNocG9pbnRzDQogDQogQHBhcmFtICBTeXN0ZW1Db250ZXh0ICAgICAgICBSZWdpc3RlciBjb250ZW50IGF0IHRpbWUgb2YgdGhlIGV4Y2VwdGlvbg0KIEBwYXJhbSAgR2RiRXhjZXB0aW9uVHlwZSAgICAgR0RCIGV4Y2VwdGlvbiB0eXBlDQogKiovDQpWT0lEDQpHZGJTZW5kVFNpZ25hbCAoDQogIElOICBFRklfU1lTVEVNX0NPTlRFWFQgIFN5c3RlbUNvbnRleHQsDQogIElOICBVSU5UOCAgICAgICAgICAgICAgIEdkYkV4Y2VwdGlvblR5cGUNCiAgKQ0Kew0KICBDSEFSOCBUU2lnbmFsQnVmZmVyWzEyOF07DQogIENIQVI4ICpUU2lnbmFsUHRyOw0KDQogIFRTaWduYWxQdHIgPSAmVFNpZ25hbEJ1ZmZlclswXTsNCg0KICAvL0NvbnN0cnVjdCBUU2lnbmFsIHBhY2tldA0KICAqVFNpZ25hbFB0cisrID0gJ1QnOw0KDQogIC8vDQogIC8vIHJlcGxhY2UgXywgb3IgcHJldmlvdXMgdmFsdWUsIHdpdGggRXhjZXB0aW9uIHR5cGUNCiAgLy8NCiAgKlRTaWduYWxQdHIrKyA9IG1IZXhUb1N0ciBbR2RiRXhjZXB0aW9uVHlwZSA+PiA0XTsgDQogICpUU2lnbmFsUHRyKysgPSBtSGV4VG9TdHIgW0dkYkV4Y2VwdGlvblR5cGUgJiAweDBmXTsNCiAgDQogIFByb2Nlc3NvclNlbmRUU2lnbmFsIChTeXN0ZW1Db250ZXh0LCBHZGJFeGNlcHRpb25UeXBlLCBUU2lnbmFsUHRyLCBzaXplb2YgKFRTaWduYWxCdWZmZXIpIC0gMik7DQoNCiAgU2VuZFBhY2tldCAoVFNpZ25hbEJ1ZmZlcik7IA0KfQ0KDQpWT0lEDQpHZGJGV3JpdGUgKA0KICBJTiAgVUlOVE4gRmQsDQogIElOICBDSEFSOCAqRGF0YSwNCiAgSU4gIFVJTlROIERhdGFTaXplDQogICkNCnsNCiAgQ0hBUjggQnVmZmVyWzEyOF07DQoNCiAgQXNjaWlTUHJpbnQgKEJ1ZmZlciwgc2l6ZW9mIChCdWZmZXIpLCAiRndyaXRlLCV4LCV4LCV4IiwgRmQsIERhdGEsIERhdGFTaXplKTsNCiAgU2VuZFBhY2tldCAoQnVmZmVyKTsNCg0KICBmb3IoIDsgOyApIHsNCiAgICBSZWNlaXZlUGFja2V0IChnSW5CdWZmZXIsIE1BWF9CVUZfU0laRSk7DQogICAgDQogICAgc3dpdGNoIChnSW5CdWZmZXJbMF0pIHsNCiAgICBjYXNlICdtJzoNCiAgICAgIFJlYWRGcm9tTWVtb3J5IChnSW5CdWZmZXIpOw0KICAgICAgYnJlYWs7DQoNCiAgICBjYXNlICdNJzoNCiAgICAgIFdyaXRlVG9NZW1vcnkgKGdJbkJ1ZmZlcik7DQogICAgICBicmVhazsNCg0KICAgIGNhc2UgJ0YnOg0KICAgICAgcmV0dXJuOw0KICAgIH0NCiAgfQ0KfQ0KDQoNClZPSUQNCkdkYkZQdXRTdHJpbmcgKA0KICBJTiBDSEFSOCAgKlN0cmluZw0KICApDQp7DQogIFVJTlROIExlbiA9IEFzY2lpU3RyU2l6ZSAoU3RyaW5nKTsNCg0KICBHZGJGV3JpdGUgKDIsIFN0cmluZywgTGVuKTsNCn0NCg0KDQovKioNCiBFeGNlcHRpb24gSGFubGRsZXIgZm9yIEdEQi4gSXQgd2lsbCBiZSBjYWxsZWQgZm9yIGFsbCBleGNlcHRpb25zDQogcmVnaXN0ZXJlZCB2aWEgdGhlIGdFeGNlcHRpb25UeXBlW10gYXJyYXkuDQogDQogQHBhcmFtIEV4Y2VwdGlvblR5cGUgICAgIEV4Y2VwdGlvbiB0aGF0IGlzIGJlaW5nIHByb2Nlc3NlZA0KIEBwYXJhbSBTeXN0ZW1Db250ZXh0ICAgICBSZWdpc3RlciBjb250ZW50IGF0IHRpbWUgb2YgdGhlIGV4Y2VwdGlvbiAgDQogKiovDQpWT0lEDQpFRklBUEkNCkdkYkV4Y2VwdGlvbkhhbmRsZXIgKCANCiAgSU4gIEVGSV9FWENFUFRJT05fVFlQRSAgICAgICAgRXhjZXB0aW9uVHlwZSwgDQogIElOIE9VVCBFRklfU1lTVEVNX0NPTlRFWFQgICAgIFN5c3RlbUNvbnRleHQgDQogICkNCnsNCiAgVUlOVDggICBHZGJFeGNlcHRpb25UeXBlOw0KICBDSEFSOCAgICpQdHI7DQogIA0KICBpZiAoUHJvY2Vzc29yQ29udHJvbEMgKEV4Y2VwdGlvblR5cGUsIFN5c3RlbUNvbnRleHQpKSB7DQogICAgLy8gV2UgdHJpZWQgdG8gcHJvY2VzcyBhIGNvbnRyb2wgQyBoYW5kbGVyIGFuZCB0aGVyZSBpcyBub3RoaW5nIHRvIGRvDQogICAgcmV0dXJuOw0KICB9DQoNCiAgR2RiRXhjZXB0aW9uVHlwZSA9IENvbnZlcnRFRkl0b0dEQnR5cGUgKEV4Y2VwdGlvblR5cGUpOw0KICBHZGJTZW5kVFNpZ25hbCAoU3lzdGVtQ29udGV4dCwgR2RiRXhjZXB0aW9uVHlwZSk7DQogIA0KICBmb3IoIDsgOyApIHsNCiAgICBSZWNlaXZlUGFja2V0IChnSW5CdWZmZXIsIE1BWF9CVUZfU0laRSk7DQogICAgDQogICAgc3dpdGNoIChnSW5CdWZmZXJbMF0pIHsNCiAgICAgIGNhc2UgJz8nOg0KICAgICAgICBHZGJTZW5kVFNpZ25hbCAoU3lzdGVtQ29udGV4dCwgR2RiRXhjZXB0aW9uVHlwZSk7DQogICAgICAgIGJyZWFrOw0KICAgICAgICAgIA0KICAgICAgY2FzZSAnYyc6DQogICAgICAgIENvbnRpbnVlQXRBZGRyZXNzIChTeXN0ZW1Db250ZXh0LCBnSW5CdWZmZXIpOyAgICAgICAgICANCiAgICAgICAgcmV0dXJuOw0KDQogICAgICBjYXNlICdEJzoNCiAgICAgICAgLy8gZ2RiIHdhbnRzIHRvIGRpc2Nvbm5lY3Qgc28gcmV0dXJuICJPSyIgcGFja2V0IHNpbmNlLiANCiAgICAgICAgU2VuZFN1Y2Nlc3MgKCk7DQogICAgICAgIHJldHVybjsNCg0KICAgICAgY2FzZSAnZyc6DQogICAgICAgIFJlYWRHZW5lcmFsUmVnaXN0ZXJzIChTeXN0ZW1Db250ZXh0KTsNCiAgICAgICAgYnJlYWs7DQogICAgICAgICAgDQogICAgICBjYXNlICdHJzoNCiAgICAgICAgV3JpdGVHZW5lcmFsUmVnaXN0ZXJzIChTeXN0ZW1Db250ZXh0LCBnSW5CdWZmZXIpOw0KICAgICAgICBicmVhazsNCiAgICAgICAgICANCiAgICAgIGNhc2UgJ0gnOg0KICAgICAgICAvL1JldHVybiAiT0siIHBhY2tldCBzaW5jZSB3ZSBkb24ndCBoYXZlIG1vcmUgdGhhbiBvbmUgdGhyZWFkLiANCiAgICAgICAgU2VuZFN1Y2Nlc3MgKCk7DQogICAgICAgIGJyZWFrOw0KICAgICAgICAgIA0KICAgICAgY2FzZSAnbSc6DQogICAgICAgIFJlYWRGcm9tTWVtb3J5IChnSW5CdWZmZXIpOw0KICAgICAgICBicmVhazsNCg0KICAgICAgY2FzZSAnTSc6DQogICAgICAgIFdyaXRlVG9NZW1vcnkgKGdJbkJ1ZmZlcik7DQogICAgICAgIGJyZWFrOw0KDQogICAgICBjYXNlICdQJzoNCiAgICAgICAgV3JpdGVOdGhSZWdpc3RlciAoU3lzdGVtQ29udGV4dCwgZ0luQnVmZmVyKTsNCiAgICAgICAgYnJlYWs7DQoNCiAgICAgIC8vDQogICAgICAvLyBTdGlsbCBkZWJ1Z2dpbmcgdGhpcyBjb2RlLiBOb3QgdXNlZCBpbiBEYXJ3aW4NCiAgICAgIC8vDQogICAgICBjYXNlICdxJzogDQogICAgICAgIC8vIEdlbmVyYWwgUXVlcnkgUGFja2V0cw0KICAgICAgICBpZiAoQXNjaWlTdHJuQ21wIChnSW5CdWZmZXIsICJxU3VwcG9ydGVkIiwgMTApID09IDApIHsNCiAgICAgICAgICAvLyByZXR1cm4gd2hhdCB3ZSBjdXJyZW50bHkgc3VwcG9ydCwgd2UgZG9uJ3QgcGFyc2Ugd2hhdCBnZGIgc3Vwb3J0cw0KICAgICAgICAgIEFzY2lpU1ByaW50IChnT3V0QnVmZmVyLCBNQVhfQlVGX1NJWkUsICJxWGZlcjpsaWJyYXJpZXM6cmVhZCs7UGFja2V0U2l6ZT0lZCIsIE1BWF9CVUZfU0laRSk7DQogICAgICAgICAgU2VuZFBhY2tldCAoZ091dEJ1ZmZlcik7DQogICAgICAgIH0gZWxzZSBpZiAoQXNjaWlTdHJuQ21wIChnSW5CdWZmZXIsICJxWGZlcjpsaWJyYXJpZXM6cmVhZDo6IiwgMjIpID09IDApIHsNCiAgICAgICAgICAvLyCRcVhmZXI6bGlicmFyaWVzOnJlYWQ6Om9mZnNldCxsZW5ndGgNCiAgICAgICAgICAvLyBnSW5CdWZmZXJbMjJdIGlzIG9mZnNldCBzdHJpbmcsICsrUHRyIGlzIGxlbmd0aCBzdHJpbmeSDQogICAgICAgICAgZm9yIChQdHIgPSAmZ0luQnVmZmVyWzIyXTsgKlB0ciAhPSAnLCc7IFB0cisrKTsNCiAgICAgICAgDQogICAgICAgICAgLy8gTm90IHN1cmUgaWYgbXVsdGktcmFkaXggc3VwcG9ydCBpcyByZXF1aXJlZC4gQ3VycmVudGx5IG9ubHkgc3VwcG9ydCBkZWNpbWFsDQogICAgICAgICAgUXhmZXJMaWJyYXJ5IChBc2NpaVN0ckhleFRvVWludG4gKCZnSW5CdWZmZXJbMjJdKSwgQXNjaWlTdHJIZXhUb1VpbnRuICgrK1B0cikpOw0KICAgICAgICB9IGVsc2UgaWYgKEFzY2lpU3RybkNtcCAoZ0luQnVmZmVyLCAicU9mZnNldHMiLCA4KSA9PSAwKSB7DQogICAgICAgICAgQXNjaWlTUHJpbnQgKGdPdXRCdWZmZXIsIE1BWF9CVUZfU0laRSwgIlRleHQ9MTAwMDtEYXRhPWYwMDA7QnNzPWYwMDAiKTsNCiAgICAgICAgICBTZW5kUGFja2V0IChnT3V0QnVmZmVyKTsNCiAgICAgICAgfSBlbHNlIGlmIChBc2NpaVN0cm5DbXAgKGdJbkJ1ZmZlciwgInFBdHRhY2hlZCIsIDkpID09IDApIHsNCiAgICAgICAgICAvLyByZW1vdGUgc2VydmVyIGF0dGFjaGVkIHRvIGFuIGV4aXN0aW5nIHByb2Nlc3MNCiAgICAgICAgICBTZW5kUGFja2V0ICgiMSIpOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgIC8vU2VuZCBlbXB0eSBwYWNrZXQNCiAgICAgICAgICBTZW5kTm90U3VwcG9ydGVkICgpOw0KICAgICAgICB9DQogICAgICAgIGJyZWFrOw0KDQogICAgICBjYXNlICdzJzoNCiAgICAgICAgU2luZ2xlU3RlcCAoU3lzdGVtQ29udGV4dCwgZ0luQnVmZmVyKTsgICAgICAgICAgDQogICAgICAgIHJldHVybjsNCiAgICAgICAgIA0KICAgICAgY2FzZSAneic6DQogICAgICAgIFJlbW92ZUJyZWFrUG9pbnQgKFN5c3RlbUNvbnRleHQsIGdJbkJ1ZmZlcik7DQogICAgICAgIGJyZWFrOw0KICANCiAgICAgIGNhc2UgJ1onOg0KICAgICAgICBJbnNlcnRCcmVha1BvaW50IChTeXN0ZW1Db250ZXh0LCBnSW5CdWZmZXIpOw0KICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgIA0KICAgICAgZGVmYXVsdDogIA0KICAgICAgICAvL1NlbmQgZW1wdHkgcGFja2V0DQogICAgICAgIFNlbmROb3RTdXBwb3J0ZWQgKCk7DQogICAgICAgIGJyZWFrOw0KICAgIH0NCiAgfQ0KfQ0KDQoNCg0KDQoNCg==