Ly8NCi8vIKkgQ29weXJpZ2h0IEhlbnJpayBSYXZuIDIwMDQNCi8vDQovLyBVc2UsIG1vZGlmaWNhdGlvbiBhbmQgZGlzdHJpYnV0aW9uIGFyZSBzdWJqZWN0IHRvIHRoZSBCb29zdCBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMC4NCi8vIChTZWUgYWNjb21wYW55aW5nIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yIGNvcHkgYXQgaHR0cDovL3d3dy5ib29zdC5vcmcvTElDRU5TRV8xXzAudHh0KQ0KLy8NCg0KdXNpbmcgU3lzdGVtOw0KdXNpbmcgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzOw0KDQpuYW1lc3BhY2UgRG90WkxpYg0Kew0KCS8vLyA8c3VtbWFyeT4NCgkvLy8gSW1wbGVtZW50cyB0aGUgY29tbW9uIGZ1bmN0aW9uYWxpdHkgbmVlZGVkIGZvciBhbGwgPHNlZSBjcmVmPSJDb2RlYyIvPnMNCgkvLy8gPC9zdW1tYXJ5Pg0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb2RlY0Jhc2UgOiBDb2RlYywgSURpc3Bvc2FibGUNCgl7DQoNCiAgICAgICAgI3JlZ2lvbiBEYXRhIG1lbWJlcnMNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBJbnN0YW5jZSBvZiB0aGUgaW50ZXJuYWwgemxpYiBidWZmZXIgc3RydWN0dXJlIHRoYXQgaXMNCiAgICAgICAgLy8vIHBhc3NlZCB0byBhbGwgZnVuY3Rpb25zIGluIHRoZSB6bGliIGRsbA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBpbnRlcm5hbCBaU3RyZWFtIF96dHJlYW0gPSBuZXcgWlN0cmVhbSgpOw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFRydWUgaWYgdGhlIG9iamVjdCBpbnN0YW5jZSBoYXMgYmVlbiBkaXNwb3NlZCwgZmFsc2Ugb3RoZXJ3aXNlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByb3RlY3RlZCBib29sIF9pc0Rpc3Bvc2VkID0gZmFsc2U7DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVGhlIHNpemUgb2YgdGhlIGludGVybmFsIGJ1ZmZlcnMNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHJvdGVjdGVkIGNvbnN0IGludCBrQnVmZmVyU2l6ZSA9IDE2Mzg0Ow0KDQogICAgICAgIHByaXZhdGUgYnl0ZVtdIF9vdXRCdWZmZXIgPSBuZXcgYnl0ZVtrQnVmZmVyU2l6ZV07DQogICAgICAgIHByaXZhdGUgYnl0ZVtdIF9pbkJ1ZmZlciA9IG5ldyBieXRlW2tCdWZmZXJTaXplXTsNCg0KICAgICAgICBwcml2YXRlIEdDSGFuZGxlIF9oSW5wdXQ7DQogICAgICAgIHByaXZhdGUgR0NIYW5kbGUgX2hPdXRwdXQ7DQoNCiAgICAgICAgcHJpdmF0ZSB1aW50IF9jaGVja3N1bSA9IDA7DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSA8Yz5Db2RlQmFzZTwvYz4gY2xhc3MuDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQoJCXB1YmxpYyBDb2RlY0Jhc2UoKQ0KCQl7DQogICAgICAgICAgICB0cnkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBfaElucHV0ID0gR0NIYW5kbGUuQWxsb2MoX2luQnVmZmVyLCBHQ0hhbmRsZVR5cGUuUGlubmVkKTsNCiAgICAgICAgICAgICAgICBfaE91dHB1dCA9IEdDSGFuZGxlLkFsbG9jKF9vdXRCdWZmZXIsIEdDSGFuZGxlVHlwZS5QaW5uZWQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBDbGVhblVwKGZhbHNlKTsNCiAgICAgICAgICAgICAgICB0aHJvdzsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCiAgICAgICAgI3JlZ2lvbiBDb2RlYyBNZW1iZXJzDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gT2NjdXJzIHdoZW4gbW9yZSBwcm9jZXNzZWQgZGF0YSBhcmUgYXZhaWxhYmxlLg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgZXZlbnQgRGF0YUF2YWlsYWJsZUhhbmRsZXIgRGF0YUF2YWlsYWJsZTsNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBGaXJlcyB0aGUgPHNlZSBjcmVmPSJEYXRhQXZhaWxhYmxlIi8+IGV2ZW50DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByb3RlY3RlZCB2b2lkIE9uRGF0YUF2YWlsYWJsZSgpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChfenRyZWFtLnRvdGFsX291dCA+IDApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYgKERhdGFBdmFpbGFibGUgIT0gbnVsbCkNCiAgICAgICAgICAgICAgICAgICAgRGF0YUF2YWlsYWJsZSggX291dEJ1ZmZlciwgMCwgKGludClfenRyZWFtLnRvdGFsX291dCk7DQogICAgICAgICAgICAgICAgcmVzZXRPdXRwdXQoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEFkZHMgbW9yZSBkYXRhIHRvIHRoZSBjb2RlYyB0byBiZSBwcm9jZXNzZWQuDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+Qnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBkYXRhIHRvIGJlIGFkZGVkIHRvIHRoZSBjb2RlYzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmVtYXJrcz5BZGRpbmcgZGF0YSBtYXksIG9yIG1heSBub3QsIHJhaXNlIHRoZSA8Yz5EYXRhQXZhaWxhYmxlPC9jPiBldmVudDwvcmVtYXJrcz4NCiAgICAgICAgcHVibGljIHZvaWQgQWRkKGJ5dGVbXSBkYXRhKQ0KICAgICAgICB7DQogICAgICAgICAgICBBZGQoZGF0YSwwLGRhdGEuTGVuZ3RoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEFkZHMgbW9yZSBkYXRhIHRvIHRoZSBjb2RlYyB0byBiZSBwcm9jZXNzZWQuDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+Qnl0ZSBhcnJheSBjb250YWluaW5nIHRoZSBkYXRhIHRvIGJlIGFkZGVkIHRvIHRoZSBjb2RlYzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib2Zmc2V0Ij5UaGUgaW5kZXggb2YgdGhlIGZpcnN0IGJ5dGUgdG8gYWRkIGZyb20gPGM+ZGF0YTwvYz48L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvdW50Ij5UaGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGFkZDwvcGFyYW0+DQogICAgICAgIC8vLyA8cmVtYXJrcz5BZGRpbmcgZGF0YSBtYXksIG9yIG1heSBub3QsIHJhaXNlIHRoZSA8Yz5EYXRhQXZhaWxhYmxlPC9jPiBldmVudDwvcmVtYXJrcz4NCiAgICAgICAgLy8vIDxyZW1hcmtzPlRoaXMgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhIGRlcml2ZWQgY2xhc3M8L3JlbWFya3M+DQogICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIEFkZChieXRlW10gZGF0YSwgaW50IG9mZnNldCwgaW50IGNvdW50KTsNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBGaW5pc2hlcyB1cCBhbnkgcGVuZGluZyBkYXRhIHRoYXQgbmVlZHMgdG8gYmUgcHJvY2Vzc2VkIGFuZCBoYW5kbGVkLg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHJlbWFya3M+VGhpcyBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGEgZGVyaXZlZCBjbGFzczwvcmVtYXJrcz4NCiAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgRmluaXNoKCk7DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gR2V0cyB0aGUgY2hlY2tzdW0gb2YgdGhlIGRhdGEgdGhhdCBoYXMgYmVlbiBhZGRlZCBzbyBmYXINCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIHVpbnQgQ2hlY2tzdW0geyBnZXQgeyByZXR1cm4gX2NoZWNrc3VtOyB9IH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiBEZXN0cnVjdG9yICYgSURpc3Bvc2FibGUgc3R1ZmYNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBEZXN0cm95cyB0aGlzIGluc3RhbmNlDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIH5Db2RlY0Jhc2UoKQ0KICAgICAgICB7DQogICAgICAgICAgICBDbGVhblVwKGZhbHNlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFJlbGVhc2VzIGFueSB1bm1hbmFnZWQgcmVzb3VyY2VzIGFuZCBjYWxscyB0aGUgPHNlZSBjcmVmPSJDbGVhblVwKCkiLz4gbWV0aG9kIG9mIHRoZSBkZXJpdmVkIGNsYXNzDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyB2b2lkIERpc3Bvc2UoKQ0KICAgICAgICB7DQogICAgICAgICAgICBDbGVhblVwKHRydWUpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gUGVyZm9ybXMgYW55IGNvZGVjIHNwZWNpZmljIGNsZWFudXANCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxyZW1hcmtzPlRoaXMgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhIGRlcml2ZWQgY2xhc3M8L3JlbWFya3M+DQogICAgICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIENsZWFuVXAoKTsNCg0KICAgICAgICAvLyBwZXJmb3JtcyB0aGUgcmVsZWFzZSBvZiB0aGUgaGFuZGxlcyBhbmQgY2FsbHMgdGhlIGRlcmVpdmVkIENsZWFuVXAoKQ0KICAgICAgICBwcml2YXRlIHZvaWQgQ2xlYW5VcChib29sIGlzRGlzcG9zaW5nKQ0KICAgICAgICB7DQogICAgICAgICAgICBpZiAoIV9pc0Rpc3Bvc2VkKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIENsZWFuVXAoKTsNCiAgICAgICAgICAgICAgICBpZiAoX2hJbnB1dC5Jc0FsbG9jYXRlZCkNCiAgICAgICAgICAgICAgICAgICAgX2hJbnB1dC5GcmVlKCk7DQogICAgICAgICAgICAgICAgaWYgKF9oT3V0cHV0LklzQWxsb2NhdGVkKQ0KICAgICAgICAgICAgICAgICAgICBfaE91dHB1dC5GcmVlKCk7DQoNCiAgICAgICAgICAgICAgICBfaXNEaXNwb3NlZCA9IHRydWU7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIEhlbHBlciBtZXRob2RzDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gQ29waWVzIGEgbnVtYmVyIG9mIGJ5dGVzIHRvIHRoZSBpbnRlcm5hbCBjb2RlYyBidWZmZXIgLSByZWFkeSBmb3IgcHJvY2Nlc2luZw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRhdGEiPlRoZSBieXRlIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIGRhdGEgdG8gY29weTwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic3RhcnRJbmRleCI+VGhlIGluZGV4IG9mIHRoZSBmaXJzdCBieXRlIHRvIGNvcHk8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvdW50Ij5UaGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGNvcHkgZnJvbSA8Yz5kYXRhPC9jPjwvcGFyYW0+DQogICAgICAgIHByb3RlY3RlZCB2b2lkIGNvcHlJbnB1dChieXRlW10gZGF0YSwgaW50IHN0YXJ0SW5kZXgsIGludCBjb3VudCkNCiAgICAgICAgew0KICAgICAgICAgICAgQXJyYXkuQ29weShkYXRhLCBzdGFydEluZGV4LCBfaW5CdWZmZXIsMCwgY291bnQpOw0KICAgICAgICAgICAgX3p0cmVhbS5uZXh0X2luID0gX2hJbnB1dC5BZGRyT2ZQaW5uZWRPYmplY3QoKTsNCiAgICAgICAgICAgIF96dHJlYW0udG90YWxfaW4gPSAwOw0KICAgICAgICAgICAgX3p0cmVhbS5hdmFpbF9pbiA9ICh1aW50KWNvdW50Ow0KDQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBSZXNldHMgdGhlIGludGVybmFsIG91dHB1dCBidWZmZXJzIHRvIGEga25vd24gc3RhdGUgLSByZWFkeSBmb3IgcHJvY2Vzc2luZw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZXNldE91dHB1dCgpDQogICAgICAgIHsNCiAgICAgICAgICAgIF96dHJlYW0udG90YWxfb3V0ID0gMDsNCiAgICAgICAgICAgIF96dHJlYW0uYXZhaWxfb3V0ID0ga0J1ZmZlclNpemU7DQogICAgICAgICAgICBfenRyZWFtLm5leHRfb3V0ID0gX2hPdXRwdXQuQWRkck9mUGlubmVkT2JqZWN0KCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBVcGRhdGVzIHRoZSBydW5uaW5nIGNoZWNrc3VtIHByb3BlcnR5DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibmV3U3VtIj5UaGUgbmV3IGNoZWNrc3VtIHZhbHVlPC9wYXJhbT4NCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgc2V0Q2hlY2tzdW0odWludCBuZXdTdW0pDQogICAgICAgIHsNCiAgICAgICAgICAgIF9jaGVja3N1bSA9IG5ld1N1bTsNCiAgICAgICAgfQ0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICB9DQp9DQo=