Ly8NCi8vIKkgQ29weXJpZ2h0IEhlbnJpayBSYXZuIDIwMDQNCi8vDQovLyBVc2UsIG1vZGlmaWNhdGlvbiBhbmQgZGlzdHJpYnV0aW9uIGFyZSBzdWJqZWN0IHRvIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4NCi8vIChTZWUgYWNjb21wYW55aW5nIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yIGNvcHkgYXQgaHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0KQ0KLy8NCg0KdXNpbmcgU3lzdGVtOw0KdXNpbmcgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzOw0KDQpuYW1lc3BhY2UgRG90WkxpYg0Kew0KCS8vLyA8c3VtbWFyeT4NCgkvLy8gSW1wbGVtZW50cyB0aGUgY29tbW9uIGZ1bmN0aW9uYWxpdHkgbmVlZGVkIGZvciBhbGwgPHNlZSBjcmVmPSJDb2RlYyIvPnMNCgkvLy8gPC9zdW1tYXJ5Pg0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb2RlY0Jhc2UgOiBDb2RlYywgSURpc3Bvc2FibGUNCgl7DQoNCiAgICAgICAgI3JlZ2lvbiBEYXRhIG1lbWJlcnMNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbnN0YW5jZSBvZiB0aGUgaW50ZXJuYWwgemxpYiBidWZmZXIgc3RydWN0dXJlIHRoYXQgaXMNCiAgICAgICAgLy8vIHBhc3NlZCB0byBhbGwgZnVuY3Rpb25zIGluIHRoZSB6bGliIGRsbA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBpbnRlcm5hbCBaU3RyZWFtIF96dHJlYW0gPSBuZXcgWlN0cmVhbSgpOw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFRydWUgaWYgdGhlIG9iamVjdCBpbnN0YW5jZSBoYXMgYmVlbiBkaXNwb3NlZCwgZmFsc2Ugb3RoZXJ3aXNlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByb3RlY3RlZCBib29sIF9pc0Rpc3Bvc2VkID0gZmFsc2U7DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVGhlIHNpemUgb2YgdGhlIGludGVybmFsIGJ1ZmZlcnMNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJvdGVjdGVkIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IDE2Mzg0Ow0KDQogICAgICAgIHByaXZhdGUgYnl0ZVtdIF9vdXRCdWZmZXIgPSBuZXcgYnl0ZVtrQnVmZmVyU2l6ZV07DQogICAgICAgIHByaXZhdGUgYnl0ZVtdIF9pbkJ1ZmZlciA9IG5ldyBieXRlW2tCdWZmZXJTaXplXTsNCg0KICAgICAgICBwcml2YXRlIEdDSGFuZGxlIF9oSW5wdXQ7DQogICAgICAgIHByaXZhdGUgR0NIYW5kbGUgX2hPdXRwdXQ7DQoNCiAgICAgICAgcHJpdmF0ZSB1aW50IF9jaGVja3N1bSA9IDA7DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSA8Yz5Db2RlQmFzZTwvYz4gY2xhc3MuDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQoJCXB1YmxpYyBDb2RlY0Jhc2UoKQ0KCQl7DQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfaElucHV0ID0gR0NIYW5kbGUuQWxsb2MoX2luQnVmZmVyLCBHQ0hhbmRsZVR5cGUuUGlubmVkKTsNCiAgICAgICAgICAgICAgICBfaE91dHB1dCA9IEdDSGFuZGxlLkFsbG9jKF9vdXRCdWZmZXIsIEdDSGFuZGxlVHlwZS5QaW5uZWQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBDbGVhblVwKGZhbHNlKTsNCiAgICAgICAgICAgICAgICB0aHJvdzsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCiAgICAgICAgI3JlZ2lvbiBDb2RlYyBNZW1iZXJzDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gT2NjdXJzIHdoZW4gbW9yZSBwcm9jZXNzZWQgZGF0YSBhcmUgYXZhaWxhYmxlLg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgZXZlbnQgRGF0YUF2YWlsYWJsZUhhbmRsZXIgRGF0YUF2YWlsYWJsZTsNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBGaXJlcyB0aGUgPHNlZSBjcmVmPSJEYXRhQXZhaWxhYmxlIi8+IGV2ZW50DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByb3RlY3RlZCB2b2lkIE9uRGF0YUF2YWlsYWJsZSgpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChfenRyZWFtLnRvdGFsX291dCA+IDApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYgKERhdGFBdmFpbGFibGUgIT0gbnVsbCkNCiAgICAgICAgICAgICAgICAgICAgRGF0YUF2YWlsYWJsZSggX291dEJ1ZmZlciwgMCwgKGludClfenRyZWFtLnRvdGFsX291dCk7DQogICAgICAgICAgICAgICAgcmVzZXRPdXRwdXQoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEFkZHMgbW9yZSBkYXRhIHRvIHRoZSBjb2RlYyB0byBiZSBwcm9jZXNzZWQuDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+Qnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBkYXRhIHRvIGJlIGFkZGVkIHRvIHRoZSBjb2RlYzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmVtYXJrcz5BZGRpbmcgZGF0YSBtYXksIG9yIG1heSBub3QsIHJhaXNlIHRoZSA8Yz5EYXRhQXZhaWxhYmxlPC9jPiBldmVudDwvcmVtYXJrcz4NCiAgICAgICAgcHVibGljIHZvaWQgQWRkKGJ5dGVbXSBkYXRhKQ0KICAgICAgICB7DQogICAgICAgICAgICBBZGQoZGF0YSwwLGRhdGEuTGVuZ3RoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEFkZHMgbW9yZSBkYXRhIHRvIHRoZSBjb2RlYyB0byBiZSBwcm9jZXNzZWQuDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+Qnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBkYXRhIHRvIGJlIGFkZGVkIHRvIHRoZSBjb2RlYzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib2Zmc2V0Ij5UaGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ5dGUgdG8gYWRkIGZyb20gPGM+ZGF0YTwvYz48L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvdW50Ij5UaGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGFkZDwvcGFyYW0+DQogICAgICAgIC8vLyA8cmVtYXJrcz5BZGRpbmcgZGF0YSBtYXksIG9yIG1heSBub3QsIHJhaXNlIHRoZSA8Yz5EYXRhQXZhaWxhYmxlPC9jPiBldmVudDwvcmVtYXJrcz4NCiAgICAgICAgLy8vIDxyZW1hcmtzPlRoaXMgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhIGRlcml2ZWQgY2xhc3M8L3JlbWFya3M+DQogICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIEFkZChieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGNvdW50KTsNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBGaW5pc2hlcyB1cCBhbnkgcGVuZGluZyBkYXRhIHRoYXQgbmVlZHMgdG8gYmUgcHJvY2Vzc2VkIGFuZCBoYW5kbGVkLg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHJlbWFya3M+VGhpcyBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGEgZGVyaXZlZCBjbGFzczwvcmVtYXJrcz4NCiAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgRmluaXNoKCk7DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gR2V0cyB0aGUgY2hlY2tzdW0gb2YgdGhlIGRhdGEgdGhhdCBoYXMgYmVlbiBhZGRlZCBzbyBmYXINCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIHVpbnQgQ2hlY2tzdW0geyBnZXQgeyByZXR1cm4gX2NoZWNrc3VtOyB9IH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiBEZXN0cnVjdG9yICYgSURpc3Bvc2FibGUgc3R1ZmYNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBEZXN0cm95cyB0aGlzIGluc3RhbmNlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIH5Db2RlY0Jhc2UoKQ0KICAgICAgICB7DQogICAgICAgICAgICBDbGVhblVwKGZhbHNlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFJlbGVhc2VzIGFueSB1bm1hbmFnZWQgcmVzb3VyY2VzIGFuZCBjYWxscyB0aGUgPHNlZSBjcmVmPSJDbGVhblVwKCkiLz4gbWV0aG9kIG9mIHRoZSBkZXJpdmVkIGNsYXNzDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyB2b2lkIERpc3Bvc2UoKQ0KICAgICAgICB7DQogICAgICAgICAgICBDbGVhblVwKHRydWUpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gUGVyZm9ybXMgYW55IGNvZGVjIHNwZWNpZmljIGNsZWFudXANCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxyZW1hcmtzPlRoaXMgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhIGRlcml2ZWQgY2xhc3M8L3JlbWFya3M+DQogICAgICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIENsZWFuVXAoKTsNCg0KICAgICAgICAvLyBwZXJmb3JtcyB0aGUgcmVsZWFzZSBvZiB0aGUgaGFuZGxlcyBhbmQgY2FsbHMgdGhlIGRlcml2ZWQgQ2xlYW5VcCgpDQogICAgICAgIHByaXZhdGUgdm9pZCBDbGVhblVwKGJvb2wgaXNEaXNwb3NpbmcpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmICghX2lzRGlzcG9zZWQpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgQ2xlYW5VcCgpOw0KICAgICAgICAgICAgICAgIGlmIChfaElucHV0LklzQWxsb2NhdGVkKQ0KICAgICAgICAgICAgICAgICAgICBfaElucHV0LkZyZWUoKTsNCiAgICAgICAgICAgICAgICBpZiAoX2hPdXRwdXQuSXNBbGxvY2F0ZWQpDQogICAgICAgICAgICAgICAgICAgIF9oT3V0cHV0LkZyZWUoKTsNCg0KICAgICAgICAgICAgICAgIF9pc0Rpc3Bvc2VkID0gdHJ1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24gSGVscGVyIG1ldGhvZHMNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBDb3BpZXMgYSBudW1iZXIgb2YgYnl0ZXMgdG8gdGhlIGludGVybmFsIGNvZGVjIGJ1ZmZlciAtIHJlYWR5IGZvciBwcm9jZXNzaW5nDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIGJ5dGUgYXJyYXkgdGhhdCBjb250YWlucyB0aGUgZGF0YSB0byBjb3B5PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzdGFydEluZGV4Ij5UaGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ5dGUgdG8gY29weTwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY291bnQiPlRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gY29weSBmcm9tIDxjPmRhdGE8L2M+PC9wYXJhbT4NCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgY29weUlucHV0KGJ5dGVbXSBkYXRhLCBpbnQgc3RhcnRJbmRleCwgaW50IGNvdW50KQ0KICAgICAgICB7DQogICAgICAgICAgICBBcnJheS5Db3B5KGRhdGEsIHN0YXJ0SW5kZXgsIF9pbkJ1ZmZlciwwLCBjb3VudCk7DQogICAgICAgICAgICBfenRyZWFtLm5leHRfaW4gPSBfaElucHV0LkFkZHJPZlBpbm5lZE9iamVjdCgpOw0KICAgICAgICAgICAgX3p0cmVhbS50b3RhbF9pbiA9IDA7DQogICAgICAgICAgICBfenRyZWFtLmF2YWlsX2luID0gKHVpbnQpY291bnQ7DQoNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFJlc2V0cyB0aGUgaW50ZXJuYWwgb3V0cHV0IGJ1ZmZlcnMgdG8gYSBrbm93biBzdGF0ZSAtIHJlYWR5IGZvciBwcm9jZXNzaW5nDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByb3RlY3RlZCB2b2lkIHJlc2V0T3V0cHV0KCkNCiAgICAgICAgew0KICAgICAgICAgICAgX3p0cmVhbS50b3RhbF9vdXQgPSAwOw0KICAgICAgICAgICAgX3p0cmVhbS5hdmFpbF9vdXQgPSBrQnVmZmVyU2l6ZTsNCiAgICAgICAgICAgIF96dHJlYW0ubmV4dF9vdXQgPSBfaE91dHB1dC5BZGRyT2ZQaW5uZWRPYmplY3QoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFVwZGF0ZXMgdGhlIHJ1bm5pbmcgY2hlY2tzdW0gcHJvcGVydHkNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJuZXdTdW0iPlRoZSBuZXcgY2hlY2tzdW0gdmFsdWU8L3BhcmFtPg0KICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzZXRDaGVja3N1bSh1aW50IG5ld1N1bSkNCiAgICAgICAgew0KICAgICAgICAgICAgX2NoZWNrc3VtID0gbmV3U3VtOw0KICAgICAgICB9DQogICAgICAgICNlbmRyZWdpb24NCg0KICAgIH0NCn0NCg==