Ly8NCi8vIKkgQ29weXJpZ2h0IEhlbnJpayBSYXZuIDIwMDQNCi8vDQovLyBVc2UsIG1vZGlmaWNhdGlvbiBhbmQgZGlzdHJpYnV0aW9uIGFyZSBzdWJqZWN0IHRvIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4gDQovLyAoU2VlIGFjY29tcGFueWluZyBmaWxlIExJQ0VOU0VfMV8wLnR4dCBvciBjb3B5IGF0IGh0dHA6Ly93d3cuYm9vc3Qub3JnL0xJQ0VOU0VfMV8wLnR4dCkNCi8vDQoNCnVzaW5nIFN5c3RlbTsNCnVzaW5nIFN5c3RlbS5Db2xsZWN0aW9uczsNCnVzaW5nIFN5c3RlbS5JTzsNCg0KLy8gdW5jb21tZW50IHRoZSBkZWZpbmUgYmVsb3cgdG8gaW5jbHVkZSB1bml0IHRlc3RzDQovLyNkZWZpbmUgbnVuaXQNCiNpZiBudW5pdA0KdXNpbmcgTlVuaXQuRnJhbWV3b3JrOw0KDQovLyBVbml0IHRlc3RzIGZvciB0aGUgRG90WkxpYiBjbGFzcyBsaWJyYXJ5DQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQovLw0KLy8gVXNlIHRoaXMgd2l0aCBOVW5pdCAyIGZyb20gaHR0cDovL3d3dy5udW5pdC5vcmcNCi8vDQoNCm5hbWVzcGFjZSBEb3RaTGliVGVzdHMNCnsNCiAgICB1c2luZyBEb3RaTGliOw0KDQogICAgLy8gaGVscGVyIG1ldGhvZHMNCiAgICBpbnRlcm5hbCBjbGFzcyBVdGlscw0KICAgIHsNCiAgICAgICAgcHVibGljIHN0YXRpYyBib29sIGJ5dGVBcnJFcXVhbCggYnl0ZVtdIGxocywgYnl0ZVtdIHJocyApDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChsaHMuTGVuZ3RoICE9IHJocy5MZW5ndGgpDQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxocy5MZW5ndGgtMTsgaSA+PSAwOyAtLWkpDQogICAgICAgICAgICAgICAgaWYgKGxoc1tpXSAhPSByaHNbaV0pDQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsNCiAgICAgICAgICAgIHJldHVybiB0cnVlOw0KICAgICAgICB9DQoNCiAgICB9DQoNCg0KICAgIFtUZXN0Rml4dHVyZV0NCiAgICBwdWJsaWMgY2xhc3MgQ2lyY0J1ZmZlclRlc3RzDQogICAgew0KICAgICAgICAjcmVnaW9uIENpcmN1bGFyIGJ1ZmZlciB0ZXN0cw0KICAgICAgICBbVGVzdF0NCiAgICAgICAgcHVibGljIHZvaWQgU2luZ2xlUHV0R2V0KCkNCiAgICAgICAgew0KICAgICAgICAgICAgQ2lyY3VsYXJCdWZmZXIgYnVmID0gbmV3IENpcmN1bGFyQnVmZmVyKDEwKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCggMCwgYnVmLlNpemUgKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCggLTEsIGJ1Zi5HZXQoKSApOw0KDQogICAgICAgICAgICBBc3NlcnQuSXNUcnVlKGJ1Zi5QdXQoIDEgKSk7DQogICAgICAgICAgICBBc3NlcnQuQXJlRXF1YWwoIDEsIGJ1Zi5TaXplICk7DQogICAgICAgICAgICBBc3NlcnQuQXJlRXF1YWwoIDEsIGJ1Zi5HZXQoKSApOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKCAwLCBidWYuU2l6ZSApOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKCAtMSwgYnVmLkdldCgpICk7DQogICAgICAgIH0NCg0KICAgICAgICBbVGVzdF0NCiAgICAgICAgcHVibGljIHZvaWQgQmxvY2tQdXRHZXQoKQ0KICAgICAgICB7DQogICAgICAgICAgICBDaXJjdWxhckJ1ZmZlciBidWYgPSBuZXcgQ2lyY3VsYXJCdWZmZXIoMTApOw0KICAgICAgICAgICAgYnl0ZVtdIGFyciA9IHsxLDIsMyw0LDUsNiw3LDgsOSwxMH07DQogICAgICAgICAgICBBc3NlcnQuQXJlRXF1YWwoIDEwLCBidWYuUHV0KGFyciwwLDEwKSApOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKCAxMCwgYnVmLlNpemUgKTsNCiAgICAgICAgICAgIEFzc2VydC5Jc0ZhbHNlKCBidWYuUHV0KDExKSApOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKCAxLCBidWYuR2V0KCkgKTsNCiAgICAgICAgICAgIEFzc2VydC5Jc1RydWUoIGJ1Zi5QdXQoMTEpICk7DQoNCiAgICAgICAgICAgIGJ5dGVbXSBhcnIyID0gKGJ5dGVbXSlhcnIuQ2xvbmUoKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCggOSwgYnVmLkdldChhcnIyLDEsOSkgKTsNCiAgICAgICAgICAgIEFzc2VydC5Jc1RydWUoIFV0aWxzLmJ5dGVBcnJFcXVhbChhcnIsYXJyMikgKTsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCiAgICB9DQoNCiAgICBbVGVzdEZpeHR1cmVdDQogICAgcHVibGljIGNsYXNzIENoZWNrc3VtVGVzdHMNCiAgICB7DQogICAgICAgICNyZWdpb24gQ1JDMzIgVGVzdHMNCiAgICAgICAgW1Rlc3RdDQogICAgICAgIHB1YmxpYyB2b2lkIENSQzMyX051bGwoKQ0KICAgICAgICB7DQogICAgICAgICAgICBDUkMzMkNoZWNrc3VtIGNyYzMyID0gbmV3IENSQzMyQ2hlY2tzdW0oKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCggMCwgY3JjMzIuVmFsdWUgKTsNCg0KICAgICAgICAgICAgY3JjMzIgPSBuZXcgQ1JDMzJDaGVja3N1bSgxKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCggMSwgY3JjMzIuVmFsdWUgKTsNCg0KICAgICAgICAgICAgY3JjMzIgPSBuZXcgQ1JDMzJDaGVja3N1bSg1NTYpOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKCA1NTYsIGNyYzMyLlZhbHVlICk7DQogICAgICAgIH0NCg0KICAgICAgICBbVGVzdF0NCiAgICAgICAgcHVibGljIHZvaWQgQ1JDMzJfRGF0YSgpDQogICAgICAgIHsNCiAgICAgICAgICAgIENSQzMyQ2hlY2tzdW0gY3JjMzIgPSBuZXcgQ1JDMzJDaGVja3N1bSgpOw0KICAgICAgICAgICAgYnl0ZVtdIGRhdGEgPSB7IDEsMiwzLDQsNSw2LDcgfTsNCiAgICAgICAgICAgIGNyYzMyLlVwZGF0ZShkYXRhKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCggMHg3MGU0Njg4OCwgY3JjMzIuVmFsdWUgICk7DQoNCiAgICAgICAgICAgIGNyYzMyID0gbmV3IENSQzMyQ2hlY2tzdW0oKTsNCiAgICAgICAgICAgIGNyYzMyLlVwZGF0ZSgicGVuZ3VpbiIpOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKCAweDBlNWMxYTEyMCwgY3JjMzIuVmFsdWUgKTsNCg0KICAgICAgICAgICAgY3JjMzIgPSBuZXcgQ1JDMzJDaGVja3N1bSgxKTsNCiAgICAgICAgICAgIGNyYzMyLlVwZGF0ZSgicGVuZ3VpbiIpOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKDB4NDNiNmFhOTQsIGNyYzMyLlZhbHVlKTsNCg0KICAgICAgICB9DQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIEFkbGVyIHRlc3RzDQoNCiAgICAgICAgW1Rlc3RdDQogICAgICAgIHB1YmxpYyB2b2lkIEFkbGVyX051bGwoKQ0KICAgICAgICB7DQogICAgICAgICAgICBBZGxlckNoZWNrc3VtIGFkbGVyID0gbmV3IEFkbGVyQ2hlY2tzdW0oKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCgwLCBhZGxlci5WYWx1ZSk7DQoNCiAgICAgICAgICAgIGFkbGVyID0gbmV3IEFkbGVyQ2hlY2tzdW0oMSk7DQogICAgICAgICAgICBBc3NlcnQuQXJlRXF1YWwoIDEsIGFkbGVyLlZhbHVlICk7DQoNCiAgICAgICAgICAgIGFkbGVyID0gbmV3IEFkbGVyQ2hlY2tzdW0oNTU2KTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCggNTU2LCBhZGxlci5WYWx1ZSApOw0KICAgICAgICB9DQoNCiAgICAgICAgW1Rlc3RdDQogICAgICAgIHB1YmxpYyB2b2lkIEFkbGVyX0RhdGEoKQ0KICAgICAgICB7DQogICAgICAgICAgICBBZGxlckNoZWNrc3VtIGFkbGVyID0gbmV3IEFkbGVyQ2hlY2tzdW0oMSk7DQogICAgICAgICAgICBieXRlW10gZGF0YSA9IHsgMSwyLDMsNCw1LDYsNyB9Ow0KICAgICAgICAgICAgYWRsZXIuVXBkYXRlKGRhdGEpOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKCAweDViMDAxZCwgYWRsZXIuVmFsdWUgICk7DQoNCiAgICAgICAgICAgIGFkbGVyID0gbmV3IEFkbGVyQ2hlY2tzdW0oKTsNCiAgICAgICAgICAgIGFkbGVyLlVwZGF0ZSgicGVuZ3VpbiIpOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKDB4MGJjZjAyZjYsIGFkbGVyLlZhbHVlICk7DQoNCiAgICAgICAgICAgIGFkbGVyID0gbmV3IEFkbGVyQ2hlY2tzdW0oMSk7DQogICAgICAgICAgICBhZGxlci5VcGRhdGUoInBlbmd1aW4iKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCgweDBiZDYwMmY3LCBhZGxlci5WYWx1ZSk7DQoNCiAgICAgICAgfQ0KICAgICAgICAjZW5kcmVnaW9uDQogICAgfQ0KDQogICAgW1Rlc3RGaXh0dXJlXQ0KICAgIHB1YmxpYyBjbGFzcyBJbmZvVGVzdHMNCiAgICB7DQogICAgICAgICNyZWdpb24gSW5mbyB0ZXN0cw0KICAgICAgICBbVGVzdF0NCiAgICAgICAgcHVibGljIHZvaWQgSW5mb19WZXJzaW9uKCkNCiAgICAgICAgew0KICAgICAgICAgICAgSW5mbyBpbmZvID0gbmV3IEluZm8oKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCgiMS4yLjMiLCBJbmZvLlZlcnNpb24pOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKDMyLCBpbmZvLlNpemVPZlVJbnQpOw0KICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKDMyLCBpbmZvLlNpemVPZlVMb25nKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCgzMiwgaW5mby5TaXplT2ZQb2ludGVyKTsNCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCgzMiwgaW5mby5TaXplT2ZPZmZzZXQpOw0KICAgICAgICB9DQogICAgICAgICNlbmRyZWdpb24NCiAgICB9DQoNCiAgICBbVGVzdEZpeHR1cmVdDQogICAgcHVibGljIGNsYXNzIERlZmxhdGVJbmZsYXRlVGVzdHMNCiAgICB7DQogICAgICAgICNyZWdpb24gRGVmbGF0ZSB0ZXN0cw0KICAgICAgICBbVGVzdF0NCiAgICAgICAgcHVibGljIHZvaWQgRGVmbGF0ZV9Jbml0KCkNCiAgICAgICAgew0KICAgICAgICAgICAgdXNpbmcgKERlZmxhdGVyIGRlZiA9IG5ldyBEZWZsYXRlcihDb21wcmVzc0xldmVsLkRlZmF1bHQpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgcHJpdmF0ZSBBcnJheUxpc3QgY29tcHJlc3NlZERhdGEgPSBuZXcgQXJyYXlMaXN0KCk7DQogICAgICAgIHByaXZhdGUgdWludCBhZGxlcjE7DQoNCiAgICAgICAgcHJpdmF0ZSBBcnJheUxpc3QgdW5jb21wcmVzc2VkRGF0YSA9IG5ldyBBcnJheUxpc3QoKTsNCiAgICAgICAgcHJpdmF0ZSB1aW50IGFkbGVyMjsNCg0KICAgICAgICBwdWJsaWMgdm9pZCBDRGF0YUF2YWlsKGJ5dGVbXSBkYXRhLCBpbnQgc3RhcnRJbmRleCwgaW50IGNvdW50KQ0KICAgICAgICB7DQogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgICAgICAgICAgICAgY29tcHJlc3NlZERhdGEuQWRkKGRhdGFbaStzdGFydEluZGV4XSk7DQogICAgICAgIH0NCg0KICAgICAgICBbVGVzdF0NCiAgICAgICAgcHVibGljIHZvaWQgRGVmbGF0ZV9Db21wcmVzcygpDQogICAgICAgIHsNCiAgICAgICAgICAgIGNvbXByZXNzZWREYXRhLkNsZWFyKCk7DQoNCiAgICAgICAgICAgIGJ5dGVbXSB0ZXN0RGF0YSA9IG5ldyBieXRlWzM1MDAwXTsNCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGVzdERhdGEuTGVuZ3RoOyArK2kpDQogICAgICAgICAgICAgICAgdGVzdERhdGFbaV0gPSA1Ow0KDQogICAgICAgICAgICB1c2luZyAoRGVmbGF0ZXIgZGVmID0gbmV3IERlZmxhdGVyKChDb21wcmVzc0xldmVsKTUpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGRlZi5EYXRhQXZhaWxhYmxlICs9IG5ldyBEYXRhQXZhaWxhYmxlSGFuZGxlcihDRGF0YUF2YWlsKTsNCiAgICAgICAgICAgICAgICBkZWYuQWRkKHRlc3REYXRhKTsNCiAgICAgICAgICAgICAgICBkZWYuRmluaXNoKCk7DQogICAgICAgICAgICAgICAgYWRsZXIxID0gZGVmLkNoZWNrc3VtOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIEluZmxhdGUgdGVzdHMNCiAgICAgICAgW1Rlc3RdDQogICAgICAgIHB1YmxpYyB2b2lkIEluZmxhdGVfSW5pdCgpDQogICAgICAgIHsNCiAgICAgICAgICAgIHVzaW5nIChJbmZsYXRlciBpbmYgPSBuZXcgSW5mbGF0ZXIoKSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHByaXZhdGUgdm9pZCBERGF0YUF2YWlsKGJ5dGVbXSBkYXRhLCBpbnQgc3RhcnRJbmRleCwgaW50IGNvdW50KQ0KICAgICAgICB7DQogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyArK2kpDQogICAgICAgICAgICAgICAgdW5jb21wcmVzc2VkRGF0YS5BZGQoZGF0YVtpK3N0YXJ0SW5kZXhdKTsNCiAgICAgICAgfQ0KDQogICAgICAgIFtUZXN0XQ0KICAgICAgICBwdWJsaWMgdm9pZCBJbmZsYXRlX0V4cGFuZCgpDQogICAgICAgIHsgDQogICAgICAgICAgICB1bmNvbXByZXNzZWREYXRhLkNsZWFyKCk7DQoNCiAgICAgICAgICAgIHVzaW5nIChJbmZsYXRlciBpbmYgPSBuZXcgSW5mbGF0ZXIoKSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBpbmYuRGF0YUF2YWlsYWJsZSArPSBuZXcgRGF0YUF2YWlsYWJsZUhhbmRsZXIoRERhdGFBdmFpbCk7DQogICAgICAgICAgICAgICAgaW5mLkFkZCgoYnl0ZVtdKWNvbXByZXNzZWREYXRhLlRvQXJyYXkodHlwZW9mKGJ5dGUpKSk7DQogICAgICAgICAgICAgICAgaW5mLkZpbmlzaCgpOw0KICAgICAgICAgICAgICAgIGFkbGVyMiA9IGluZi5DaGVja3N1bTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCggYWRsZXIxLCBhZGxlcjIgKTsNCiAgICAgICAgfQ0KICAgICAgICAjZW5kcmVnaW9uDQogICAgfQ0KDQogICAgW1Rlc3RGaXh0dXJlXQ0KICAgIHB1YmxpYyBjbGFzcyBHWmlwU3RyZWFtVGVzdHMNCiAgICB7DQogICAgICAgICNyZWdpb24gR1ppcFN0cmVhbSB0ZXN0DQogICAgICAgIFtUZXN0XQ0KICAgICAgICBwdWJsaWMgdm9pZCBHWmlwU3RyZWFtX1dyaXRlUmVhZCgpDQogICAgICAgIHsNCiAgICAgICAgICAgIHVzaW5nIChHWmlwU3RyZWFtIGd6T3V0ID0gbmV3IEdaaXBTdHJlYW0oImd6c3RyZWFtLmd6IiwgQ29tcHJlc3NMZXZlbC5CZXN0KSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBCaW5hcnlXcml0ZXIgd3JpdGVyID0gbmV3IEJpbmFyeVdyaXRlcihnek91dCk7DQogICAgICAgICAgICAgICAgd3JpdGVyLldyaXRlKCJoaSB0aGVyZSIpOw0KICAgICAgICAgICAgICAgIHdyaXRlci5Xcml0ZShNYXRoLlBJKTsNCiAgICAgICAgICAgICAgICB3cml0ZXIuV3JpdGUoNDIpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICB1c2luZyAoR1ppcFN0cmVhbSBnekluID0gbmV3IEdaaXBTdHJlYW0oImd6c3RyZWFtLmd6IikpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgQmluYXJ5UmVhZGVyIHJlYWRlciA9IG5ldyBCaW5hcnlSZWFkZXIoZ3pJbik7DQogICAgICAgICAgICAgICAgc3RyaW5nIHMgPSByZWFkZXIuUmVhZFN0cmluZygpOw0KICAgICAgICAgICAgICAgIEFzc2VydC5BcmVFcXVhbCgiaGkgdGhlcmUiLHMpOw0KICAgICAgICAgICAgICAgIGRvdWJsZSBkID0gcmVhZGVyLlJlYWREb3VibGUoKTsNCiAgICAgICAgICAgICAgICBBc3NlcnQuQXJlRXF1YWwoTWF0aC5QSSwgZCk7DQogICAgICAgICAgICAgICAgaW50IGkgPSByZWFkZXIuUmVhZEludDMyKCk7DQogICAgICAgICAgICAgICAgQXNzZXJ0LkFyZUVxdWFsKDQyLGkpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgIH0NCiAgICAgICAgI2VuZHJlZ2lvbg0KCX0NCn0NCg0KI2VuZGlm