LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfY29ubmVjdGl2aXR5Lmh4eCIKI2luY2x1ZGUgImNvbm5lY3Rpdml0eS9zcWxwYXJzZS5oeHgiCiNpbmNsdWRlICJhZG8vQVByZXBhcmVkU3RhdGVtZW50Lmh4eCIKI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGJjL0RhdGFUeXBlLmhwcD4KI2luY2x1ZGUgImFkby9BUmVzdWx0U2V0TWV0YURhdGEuaHh4IgojaW5jbHVkZSAiYWRvL0FSZXN1bHRTZXQuaHh4IgojaW5jbHVkZSAiYWRvL0FEcml2ZXIuaHh4IgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2xhbmcvRGlzcG9zZWRFeGNlcHRpb24uaHBwPgojaW5jbHVkZSA8Y3BwdWhlbHBlci90eXBlcHJvdmlkZXIuaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9zZXF1ZW5jZS5oeHg+CiNpbmNsdWRlICJjb25uZWN0aXZpdHkvZGJleGNlcHRpb24uaHh4IgojaW5jbHVkZSAiY29ubmVjdGl2aXR5L2RidG9vbHMuaHh4IgojaW5jbHVkZSAicmVzb3VyY2UvYWRvX3Jlcy5ocmMiCgojaW5jbHVkZSA8bGltaXRzPgoKI2RlZmluZSBDSEVDS19SRVRVUk4oeCkJCQkJCQkJCQkJCQkJXAoJaWYoIXgpCQkJCQkJCQkJCQkJCQkJCVwKCQlBRE9TOjpUaHJvd0V4Y2VwdGlvbigqbV9wQ29ubmVjdGlvbi0+Z2V0Q29ubmVjdGlvbigpLCp0aGlzKTsKCiNpZmRlZiBtYXgKIwl1bmRlZiBtYXgKI2VuZGlmCgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp1c2luZyBuYW1lc3BhY2UgY29ubmVjdGl2aXR5OjphZG87CnVzaW5nIG5hbWVzcGFjZSBjb25uZWN0aXZpdHk7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6dW5vOwp1c2luZyBuYW1lc3BhY2UgY29tOjpzdW46OnN0YXI6Omxhbmc7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6YmVhbnM7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6c2RiYzsKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjp1dGlsOwoKCklNUExFTUVOVF9TRVJWSUNFX0lORk8oT1ByZXBhcmVkU3RhdGVtZW50LCJjb20uc3VuLnN0YXIuc2RiY3guQVByZXBhcmVkU3RhdGVtZW50IiwiY29tLnN1bi5zdGFyLnNkYmMuUHJlcGFyZWRTdGF0ZW1lbnQiKTsKCk9QcmVwYXJlZFN0YXRlbWVudDo6T1ByZXBhcmVkU3RhdGVtZW50KCBPQ29ubmVjdGlvbiogX3BDb25uZWN0aW9uLGNvbnN0IE9UeXBlSW5mb01hcCYgX1R5cGVJbmZvLGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgc3FsKQoJOiBPU3RhdGVtZW50X0Jhc2UoIF9wQ29ubmVjdGlvbiApCgksbV9hVHlwZUluZm8oX1R5cGVJbmZvKQp7Cglvc2xfaW5jcmVtZW50SW50ZXJsb2NrZWRDb3VudCggJm1fcmVmQ291bnQgKTsKCglPU1FMUGFyc2VyIGFQYXJzZXIoX3BDb25uZWN0aW9uLT5nZXREcml2ZXIoKS0+Z2V0T1JCKCkpOwoJOjpydGw6Ok9VU3RyaW5nIHNFcnJvck1lc3NhZ2U7Cgk6OnJ0bDo6T1VTdHJpbmcgc05ld1NxbDsKCU9TUUxQYXJzZU5vZGUqIHBOb2RlID0gYVBhcnNlci5wYXJzZVRyZWUoc0Vycm9yTWVzc2FnZSxzcWwpOwoJaWYocE5vZGUpCgl7CS8vIHNwZWNpYWwgaGFuZGxpbmcgZm9yIHBhcmFtZXRlcnMKICAgICAgICAvKiB3ZSByZWN1c2l2ZSByZXBsYWNlIGFsbCBvY2N1cmVuY2VzIG9mID8gaW4gdGhlIHN0YXRlbWVudCBhbmQgcmVwbGFjZSB0aGVtIHdpdGggbmFtZSBsaWtlICLmrOUiICovCgkJc2FsX0ludDMyIG5QYXJhbWV0ZXJDb3VudCA9IDA7CgkJOjpydGw6Ok9VU3RyaW5nIHNEZWZhdWx0TmFtZSA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJwYXJhbWUiKTsKCQlyZXBsYWNlUGFyYW1ldGVyTm9kZU5hbWUocE5vZGUsc0RlZmF1bHROYW1lLG5QYXJhbWV0ZXJDb3VudCk7CgkJcE5vZGUtPnBhcnNlTm9kZVRvU3RyKCBzTmV3U3FsLCBfcENvbm5lY3Rpb24gKTsKCQlkZWxldGUgcE5vZGU7Cgl9CgllbHNlCgkJc05ld1NxbCA9IHNxbDsKCUNIRUNLX1JFVFVSTihtX0NvbW1hbmQucHV0X0NvbW1hbmRUZXh0KHNOZXdTcWwpKQoJQ0hFQ0tfUkVUVVJOKG1fQ29tbWFuZC5wdXRfUHJlcGFyZWQoVkFSSUFOVF9UUlVFKSkKCW1fcFBhcmFtZXRlcnMgPSBtX0NvbW1hbmQuZ2V0X1BhcmFtZXRlcnMoKTsKCW1fcFBhcmFtZXRlcnMtPkFkZFJlZigpOwoJbV9wUGFyYW1ldGVycy0+UmVmcmVzaCgpOwoKCW9zbF9kZWNyZW1lbnRJbnRlcmxvY2tlZENvdW50KCAmbV9yZWZDb3VudCApOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9QcmVwYXJlZFN0YXRlbWVudDo6fk9QcmVwYXJlZFN0YXRlbWVudCgpCnsKCWlmIChtX3BQYXJhbWV0ZXJzKQoJewoJCU9TTF9FTlNVUkUoIHNhbF9GYWxzZSwgIk9QcmVwYXJlZFN0YXRlbWVudDo6fk9QcmVwYXJlZFN0YXRlbWVudDogbm90IGRpc3Bvc2VkISIgKTsKCQltX3BQYXJhbWV0ZXJzLT5SZWxlYXNlKCk7CgkJbV9wUGFyYW1ldGVycyA9IE5VTEw7Cgl9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkFueSBTQUxfQ0FMTCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OnF1ZXJ5SW50ZXJmYWNlKCBjb25zdCBUeXBlICYgclR5cGUgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CglBbnkgYVJldCA9IE9TdGF0ZW1lbnRfQmFzZTo6cXVlcnlJbnRlcmZhY2UoclR5cGUpOwoJcmV0dXJuIGFSZXQuaGFzVmFsdWUoKSA/IGFSZXQgOiA6OmNwcHU6OnF1ZXJ5SW50ZXJmYWNlKAlyVHlwZSwKCQkJCQkJCQkJCXN0YXRpY19jYXN0PCBYUHJlcGFyZWRTdGF0ZW1lbnQqPih0aGlzKSwKCQkJCQkJCQkJCXN0YXRpY19jYXN0PCBYUGFyYW1ldGVycyo+KHRoaXMpLAoJCQkJCQkJCQkJc3RhdGljX2Nhc3Q8IFhQcmVwYXJlZEJhdGNoRXhlY3V0aW9uKj4odGhpcyksCgkJCQkJCQkJCQlzdGF0aWNfY2FzdDwgWFJlc3VsdFNldE1ldGFEYXRhU3VwcGxpZXIqPih0aGlzKSk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlNlcXVlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlR5cGUgPiBTQUxfQ0FMTCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OmdldFR5cGVzKCAgKSB0aHJvdyg6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6Y3BwdTo6T1R5cGVDb2xsZWN0aW9uIGFUeXBlcygJOjpnZXRDcHB1VHlwZSggKGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UmVmZXJlbmNlPCBYUHJlcGFyZWRTdGF0ZW1lbnQgPiAqKTAgKSwKCQkJCQkJCQkJOjpnZXRDcHB1VHlwZSggKGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UmVmZXJlbmNlPCBYUGFyYW1ldGVycyA+ICopMCApLAoJCQkJCQkJCQk6OmdldENwcHVUeXBlKCAoY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSZWZlcmVuY2U8IFhSZXN1bHRTZXRNZXRhRGF0YVN1cHBsaWVyID4gKikwICksCgkJCQkJCQkJCTo6Z2V0Q3BwdVR5cGUoIChjb25zdCA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlJlZmVyZW5jZTwgWFByZXBhcmVkQmF0Y2hFeGVjdXRpb24gPiAqKTAgKSk7CgoJcmV0dXJuIDo6Y29tcGhlbHBlcjo6Y29uY2F0U2VxdWVuY2VzKGFUeXBlcy5nZXRUeXBlcygpLE9TdGF0ZW1lbnRfQmFzZTo6Z2V0VHlwZXMoKSk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKUmVmZXJlbmNlPCBYUmVzdWx0U2V0TWV0YURhdGEgPiBTQUxfQ0FMTCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OmdldE1ldGFEYXRhKCAgKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCWlmKCFtX3hNZXRhRGF0YS5pcygpICYmIG1fUmVjb3JkU2V0LklzVmFsaWQoKSkKCQltX3hNZXRhRGF0YSA9IG5ldyBPUmVzdWx0U2V0TWV0YURhdGEobV9SZWNvcmRTZXQpOwoJcmV0dXJuIG1feE1ldGFEYXRhOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OmRpc3Bvc2luZygpCnsKbV94TWV0YURhdGEuY2xlYXIoKTsKCWlmIChtX3BQYXJhbWV0ZXJzKQoJewoJCW1fcFBhcmFtZXRlcnMtPlJlbGVhc2UoKTsKCQltX3BQYXJhbWV0ZXJzID0gTlVMTDsKCX0KCU9TdGF0ZW1lbnRfQmFzZTo6ZGlzcG9zaW5nKCk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTQUxfQ0FMTCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OmNsb3NlKCAgKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCgl7CgkJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtX2FNdXRleCApOwoJCWNoZWNrRGlzcG9zZWQoT1N0YXRlbWVudF9CQVNFOjpyQkhlbHBlci5iRGlzcG9zZWQpOwoKCX0KCWRpc3Bvc2UoKTsKCn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc2FsX0Jvb2wgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpleGVjdXRlKCAgKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKCWNoZWNrRGlzcG9zZWQoT1N0YXRlbWVudF9CQVNFOjpyQkhlbHBlci5iRGlzcG9zZWQpOwoKCglTUUxXYXJuaW5nCXdhcm5pbmc7CgoJLy8gUmVzZXQgd2FybmluZ3MKCgljbGVhcldhcm5pbmdzICgpOwoKCS8vIFJlc2V0IHRoZSBzdGF0ZW1lbnQgaGFuZGxlLCB3YXJuaW5nIGFuZCBzYXZlZCBSZXN1bHRzZXQKCgkvLwlyZXNldCgpOwoKCS8vIENhbGwgU1FMRXhlY3V0ZQoKCXRyeSB7CgkJQURPUmVjb3Jkc2V0KiBwU2V0PU5VTEw7CgkJQ0hFQ0tfUkVUVVJOKG1fQ29tbWFuZC5FeGVjdXRlKG1fUmVjb3Jkc0FmZmVjdGVkLG1fUGFyYW1ldGVycyxhZENtZFVua25vd24sJnBTZXQpKQoJCW1fUmVjb3JkU2V0ID0gV3BBRE9SZWNvcmRzZXQocFNldCk7Cgl9CgljYXRjaCAoU1FMV2FybmluZyYgZXgpCgl7CgoJCS8vIFNhdmUgcG9pbnRlciB0byB3YXJuaW5nIGFuZCBzYXZlIHdpdGggUmVzdWx0U2V0CgkJLy8gb2JqZWN0IG9uY2UgaXQgaXMgY3JlYXRlZC4KCgkJd2FybmluZyA9IGV4OwoJfQoJcmV0dXJuIG1fUmVjb3JkU2V0LklzVmFsaWQoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzYWxfSW50MzIgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpleGVjdXRlVXBkYXRlKCAgKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKCWNoZWNrRGlzcG9zZWQoT1N0YXRlbWVudF9CQVNFOjpyQkhlbHBlci5iRGlzcG9zZWQpOwoKCglBRE9SZWNvcmRzZXQqIHBTZXQ9TlVMTDsKCUNIRUNLX1JFVFVSTihtX0NvbW1hbmQuRXhlY3V0ZShtX1JlY29yZHNBZmZlY3RlZCxtX1BhcmFtZXRlcnMsYWRDbWRVbmtub3duLCZwU2V0KSkKCWlmICggVlRfRVJST1IgPT0gbV9SZWNvcmRzQWZmZWN0ZWQuZ2V0VHlwZSgpICkKCXsKCQlBRE9TOjpUaHJvd0V4Y2VwdGlvbigqbV9wQ29ubmVjdGlvbi0+Z2V0Q29ubmVjdGlvbigpLCp0aGlzKTsKCQkvLyB0byBiZSBzdXJlIHRoYXQgd2UgZ2V0IHRoZSBlcnJvciByZWFsbHkgdGhyb3duCgkJdGhyb3cgU1FMRXhjZXB0aW9uKCk7Cgl9CgltX1JlY29yZFNldCA9IFdwQURPUmVjb3Jkc2V0KHBTZXQpOwoJcmV0dXJuICBzdGF0aWNfY2FzdDxzYWxfSW50MzI+KG1fUmVjb3Jkc0FmZmVjdGVkKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9QcmVwYXJlZFN0YXRlbWVudDo6c2V0UGFyYW1ldGVyKHNhbF9JbnQzMiBwYXJhbWV0ZXJJbmRleCwgY29uc3QgRGF0YVR5cGVFbnVtJiBfZVR5cGUsCgkJCQkJCQkJCSAgY29uc3Qgc2FsX0ludDMyJiBfblNpemUsY29uc3QgT0xFVmFyaWFudCYgX1ZhbCkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7Cgk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIG1fYU11dGV4ICk7CgljaGVja0Rpc3Bvc2VkKE9TdGF0ZW1lbnRfQkFTRTo6ckJIZWxwZXIuYkRpc3Bvc2VkKTsKCgoJc2FsX0ludDMyIG5Db3VudCA9IDA7CgltX3BQYXJhbWV0ZXJzLT5nZXRfQ291bnQoJm5Db3VudCk7CglpZihuQ291bnQgPCAocGFyYW1ldGVySW5kZXgtMSkpCgl7CgkJOjpydGw6Ok9VU3RyaW5nIHNEZWZhdWx0TmFtZSA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJwYXJhbWUiKTsKCQlzRGVmYXVsdE5hbWUgKz0gOjpydGw6Ok9VU3RyaW5nOjp2YWx1ZU9mKHBhcmFtZXRlckluZGV4KTsKCQlBRE9QYXJhbWV0ZXIqIHBQYXJhbSA9IG1fQ29tbWFuZC5DcmVhdGVQYXJhbWV0ZXIoc0RlZmF1bHROYW1lLF9lVHlwZSxhZFBhcmFtSW5wdXQsX25TaXplLF9WYWwpOwoJCWlmKHBQYXJhbSkKCQl7CgkJCW1fcFBhcmFtZXRlcnMtPkFwcGVuZChwUGFyYW0pOwojaWYgT1NMX0RFQlVHX0xFVkVMID4gMAoJCQlBRE9QYXJhbWV0ZXIqIHBQYXJhbSA9IE5VTEw7CgkJCW1fcFBhcmFtZXRlcnMtPmdldF9JdGVtKE9MRVZhcmlhbnQoc2FsX0ludDMyKHBhcmFtZXRlckluZGV4LTEpKSwmcFBhcmFtKTsKCQkJV3BBRE9QYXJhbWV0ZXIgYVBhcmFtKHBQYXJhbSk7CgkJCWlmKHBQYXJhbSkKCQkJewoJCQkJRGF0YVR5cGVFbnVtIGVUeXBlID0gYVBhcmFtLkdldEFET1R5cGUoKTsKICAgICAgICAgICAgICAgICh2b2lkKWVUeXBlOwoJCQl9CiNlbmRpZgoJCX0KCX0KCWVsc2UKCXsKCQlBRE9QYXJhbWV0ZXIqIHBQYXJhbSA9IE5VTEw7CgkJbV9wUGFyYW1ldGVycy0+Z2V0X0l0ZW0oT0xFVmFyaWFudChzYWxfSW50MzIocGFyYW1ldGVySW5kZXgtMSkpLCZwUGFyYW0pOwoJCVdwQURPUGFyYW1ldGVyIGFQYXJhbShwUGFyYW0pOwoJCWlmKHBQYXJhbSkKCQl7CiNpZiBPU0xfREVCVUdfTEVWRUwgPiAwCgkJCTo6cnRsOjpPVVN0cmluZyBzUGFyYW0gPSBhUGFyYW0uR2V0TmFtZSgpOwoKI2VuZGlmIC8vIE9TTF9ERUJVR19MRVZFTAoKCQkJRGF0YVR5cGVFbnVtIGVUeXBlID0gYVBhcmFtLkdldEFET1R5cGUoKTsKCQkJaWYgKCBfZVR5cGUgIT0gZVR5cGUgJiYgX2VUeXBlICE9IGFkREJUaW1lU3RhbXAgKQoJCQl7CgkJCQlhUGFyYW0ucHV0X1R5cGUoX2VUeXBlKTsKCQkJCWVUeXBlID0gX2VUeXBlOwoJCQkJYVBhcmFtLnB1dF9TaXplKF9uU2l6ZSk7CgkJCX0KCgkJCWlmICggYWRWYXJCaW5hcnkgPT0gZVR5cGUgJiYgYVBhcmFtLkdldEF0dHJpYnV0ZXMoKSA9PSBhZFBhcmFtTG9uZyApCgkJCXsKCQkJCWFQYXJhbS5BcHBlbmRDaHVuayhfVmFsKTsKCQkJfQoJCQllbHNlCgkJCQlDSEVDS19SRVRVUk4oYVBhcmFtLlB1dFZhbHVlKF9WYWwpKTsKCQl9Cgl9CglBRE9TOjpUaHJvd0V4Y2VwdGlvbigqbV9wQ29ubmVjdGlvbi0+Z2V0Q29ubmVjdGlvbigpLCp0aGlzKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRTdHJpbmcoIHNhbF9JbnQzMiBwYXJhbWV0ZXJJbmRleCwgY29uc3QgOjpydGw6Ok9VU3RyaW5nJiB4ICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBzZXRQYXJhbWV0ZXIoIHBhcmFtZXRlckluZGV4LCBhZExvbmdWYXJXQ2hhciwgOjpzdGQ6Om51bWVyaWNfbGltaXRzPCBzYWxfSW50MzIgPjo6bWF4KCksIHggKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpSZWZlcmVuY2U8IFhDb25uZWN0aW9uID4gU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpnZXRDb25uZWN0aW9uKCAgKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKCWNoZWNrRGlzcG9zZWQoT1N0YXRlbWVudF9CQVNFOjpyQkhlbHBlci5iRGlzcG9zZWQpOwoKCglyZXR1cm4gKFJlZmVyZW5jZTwgWENvbm5lY3Rpb24gPiltX3BDb25uZWN0aW9uOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClJlZmVyZW5jZTwgWFJlc3VsdFNldCA+IFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6ZXhlY3V0ZVF1ZXJ5KCAgKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKCWNoZWNrRGlzcG9zZWQoT1N0YXRlbWVudF9CQVNFOjpyQkhlbHBlci5iRGlzcG9zZWQpOwoKCgkvLyBmaXJzdCBjbGVhciB0aGUgb2xkIHRoaW5ncwptX3hNZXRhRGF0YS5jbGVhcigpOwoJZGlzcG9zZVJlc3VsdFNldCgpOwoJaWYobV9SZWNvcmRTZXQuSXNWYWxpZCgpKQoJCW1fUmVjb3JkU2V0LkNsb3NlKCk7CgltX1JlY29yZFNldC5jbGVhcigpOwoKCgkvLyB0aGUgY3JlYXRlIHRoZSBuZXcgb25jZXMKCW1fUmVjb3JkU2V0LkNyZWF0ZSgpOwoJT0xFVmFyaWFudCBhQ21kOwoJYUNtZC5zZXRJRGlzcGF0Y2gobV9Db21tYW5kKTsKCU9MRVZhcmlhbnQgYUNvbjsKCWFDb24uc2V0Tm9BcmcoKTsKCUNIRUNLX1JFVFVSTihtX1JlY29yZFNldC5wdXRfQ2FjaGVTaXplKG1fbkZldGNoU2l6ZSkpCglDSEVDS19SRVRVUk4obV9SZWNvcmRTZXQucHV0X01heFJlY29yZHMobV9uTWF4Um93cykpCglDSEVDS19SRVRVUk4obV9SZWNvcmRTZXQuT3BlbihhQ21kLGFDb24sbV9lQ3Vyc29yVHlwZSxtX2VMb2NrVHlwZSxhZE9wZW5VbnNwZWNpZmllZCkpCglDSEVDS19SRVRVUk4obV9SZWNvcmRTZXQuZ2V0X0NhY2hlU2l6ZShtX25GZXRjaFNpemUpKQoJQ0hFQ0tfUkVUVVJOKG1fUmVjb3JkU2V0LmdldF9NYXhSZWNvcmRzKG1fbk1heFJvd3MpKQoJQ0hFQ0tfUkVUVVJOKG1fUmVjb3JkU2V0LmdldF9DdXJzb3JUeXBlKG1fZUN1cnNvclR5cGUpKQoJQ0hFQ0tfUkVUVVJOKG1fUmVjb3JkU2V0LmdldF9Mb2NrVHlwZShtX2VMb2NrVHlwZSkpCgoJT1Jlc3VsdFNldCogcFNldCA9IG5ldyBPUmVzdWx0U2V0KG1fUmVjb3JkU2V0LHRoaXMpOwoJUmVmZXJlbmNlPCBYUmVzdWx0U2V0ID4geFJzID0gcFNldDsKCXBTZXQtPmNvbnN0cnVjdCgpOwogICAgcFNldC0+c2V0TWV0YURhdGEoZ2V0TWV0YURhdGEoKSk7CgltX3hSZXN1bHRTZXQgPSBXZWFrUmVmZXJlbmNlPFhSZXN1bHRTZXQ+KHhScyk7CgoJcmV0dXJuIHhSczsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6c2V0Qm9vbGVhbiggc2FsX0ludDMyIHBhcmFtZXRlckluZGV4LCBzYWxfQm9vbCB4ICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CglzZXRQYXJhbWV0ZXIocGFyYW1ldGVySW5kZXgsYWRCb29sZWFuLHNpemVvZih4KSx4KTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6c2V0Qnl0ZSggc2FsX0ludDMyIHBhcmFtZXRlckluZGV4LCBzYWxfSW50OCB4ICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CglzZXRQYXJhbWV0ZXIocGFyYW1ldGVySW5kZXgsYWRUaW55SW50LHNpemVvZih4KSx4KTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6c2V0RGF0ZSggc2FsX0ludDMyIHBhcmFtZXRlckluZGV4LCBjb25zdCBEYXRlJiB4ICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CglzZXRQYXJhbWV0ZXIocGFyYW1ldGVySW5kZXgsYWREQkRhdGUsc2l6ZW9mKHgpLHgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgp2b2lkIFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6c2V0VGltZSggc2FsX0ludDMyIHBhcmFtZXRlckluZGV4LCBjb25zdCBUaW1lJiB4ICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CglzZXRQYXJhbWV0ZXIocGFyYW1ldGVySW5kZXgsYWREQlRpbWUsc2l6ZW9mKHgpLHgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRUaW1lc3RhbXAoIHNhbF9JbnQzMiBwYXJhbWV0ZXJJbmRleCwgY29uc3QgRGF0ZVRpbWUmIHggKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCXNldFBhcmFtZXRlcihwYXJhbWV0ZXJJbmRleCxhZERCVGltZVN0YW1wLHNpemVvZih4KSx4KTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6c2V0RG91YmxlKCBzYWxfSW50MzIgcGFyYW1ldGVySW5kZXgsIGRvdWJsZSB4ICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CglzZXRQYXJhbWV0ZXIocGFyYW1ldGVySW5kZXgsYWREb3VibGUsc2l6ZW9mKHgpLHgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRGbG9hdCggc2FsX0ludDMyIHBhcmFtZXRlckluZGV4LCBmbG9hdCB4ICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CglzZXRQYXJhbWV0ZXIocGFyYW1ldGVySW5kZXgsYWRTaW5nbGUsc2l6ZW9mKHgpLHgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRJbnQoIHNhbF9JbnQzMiBwYXJhbWV0ZXJJbmRleCwgc2FsX0ludDMyIHggKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCXNldFBhcmFtZXRlcihwYXJhbWV0ZXJJbmRleCxhZEludGVnZXIsc2l6ZW9mKHgpLHgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRMb25nKCBzYWxfSW50MzIgcGFyYW1ldGVySW5kZXgsIHNhbF9JbnQ2NCB4ICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CglzZXRQYXJhbWV0ZXIocGFyYW1ldGVySW5kZXgsYWRCaWdJbnQsc2l6ZW9mKHgpLHgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXROdWxsKCBzYWxfSW50MzIgcGFyYW1ldGVySW5kZXgsIHNhbF9JbnQzMiAvKnNxbFR5cGUqLyApIHRocm93KFNRTEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKewoJT0xFVmFyaWFudCBhVmFsOwoJYVZhbC5zZXROdWxsKCk7CglzZXRQYXJhbWV0ZXIocGFyYW1ldGVySW5kZXgsYWRFbXB0eSwwLGFWYWwpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRDbG9iKCBzYWxfSW50MzIgLypwYXJhbWV0ZXJJbmRleCovLCBjb25zdCBSZWZlcmVuY2U8IFhDbG9iID4mIC8qeCovICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CiAgICA6OmRidG9vbHM6OnRocm93RmVhdHVyZU5vdEltcGxlbWVudGVkRXhjZXB0aW9uKCAiWFJvd1VwZGF0ZTo6c2V0Q2xvYiIsICp0aGlzICk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTQUxfQ0FMTCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OnNldEJsb2IoIHNhbF9JbnQzMiAvKnBhcmFtZXRlckluZGV4Ki8sIGNvbnN0IFJlZmVyZW5jZTwgWEJsb2IgPiYgLyp4Ki8gKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIDo6ZGJ0b29sczo6dGhyb3dGZWF0dXJlTm90SW1wbGVtZW50ZWRFeGNlcHRpb24oICJYUm93VXBkYXRlOjpzZXRCbG9iIiwgKnRoaXMgKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6c2V0QXJyYXkoIHNhbF9JbnQzMiAvKnBhcmFtZXRlckluZGV4Ki8sIGNvbnN0IFJlZmVyZW5jZTwgWEFycmF5ID4mIC8qeCovICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CiAgICA6OmRidG9vbHM6OnRocm93RmVhdHVyZU5vdEltcGxlbWVudGVkRXhjZXB0aW9uKCAiWFJvd1VwZGF0ZTo6c2V0QXJyYXkiLCAqdGhpcyApOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRSZWYoIHNhbF9JbnQzMiAvKnBhcmFtZXRlckluZGV4Ki8sIGNvbnN0IFJlZmVyZW5jZTwgWFJlZiA+JiAvKngqLyApIHRocm93KFNRTEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKewogICAgOjpkYnRvb2xzOjp0aHJvd0ZlYXR1cmVOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbiggIlhSb3dVcGRhdGU6OnNldFJlZiIsICp0aGlzICk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTQUxfQ0FMTCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OnNldE9iamVjdFdpdGhJbmZvKCBzYWxfSW50MzIgcGFyYW1ldGVySW5kZXgsIGNvbnN0IEFueSYgeCwgc2FsX0ludDMyIHNxbFR5cGUsIHNhbF9JbnQzMiBzY2FsZSApIHRocm93KFNRTEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKewogICAgc3dpdGNoKHNxbFR5cGUpCgl7CiAgICAgICAgY2FzZSBEYXRhVHlwZTo6REVDSU1BTDoKICAgICAgICBjYXNlIERhdGFUeXBlOjpOVU1FUklDOgogICAgICAgICAgICBzZXRTdHJpbmcocGFyYW1ldGVySW5kZXgsOjpjb21waGVscGVyOjpnZXRTdHJpbmcoeCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICA6OmRidG9vbHM6OnNldE9iamVjdFdpdGhJbmZvKHRoaXMscGFyYW1ldGVySW5kZXgseCxzcWxUeXBlLHNjYWxlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTQUxfQ0FMTCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OnNldE9iamVjdE51bGwoIHNhbF9JbnQzMiBwYXJhbWV0ZXJJbmRleCwgc2FsX0ludDMyIHNxbFR5cGUsIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgLyp0eXBlTmFtZSovICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CglzZXROdWxsKHBhcmFtZXRlckluZGV4LHNxbFR5cGUpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRPYmplY3QoIHNhbF9JbnQzMiBwYXJhbWV0ZXJJbmRleCwgY29uc3QgQW55JiB4ICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBpZighOjpkYnRvb2xzOjppbXBsU2V0T2JqZWN0KHRoaXMscGFyYW1ldGVySW5kZXgseCkpCgl7CiAgICAgICAgY29uc3QgOjpydGw6Ok9VU3RyaW5nIHNFcnJvciggbV9wQ29ubmVjdGlvbi0+Z2V0UmVzb3VyY2VzKCkuZ2V0UmVzb3VyY2VTdHJpbmdXaXRoU3Vic3RpdHV0aW9uKAogICAgICAgICAgICAgICAgU1RSX1VOS05PV05fUEFSQV9UWVBFLAogICAgICAgICAgICAgICAgIiRwb3NpdGlvbiQiLCA6OnJ0bDo6T1VTdHJpbmc6OnZhbHVlT2YocGFyYW1ldGVySW5kZXgpCiAgICAgICAgICAgICApICk7CgkJOjpkYnRvb2xzOjp0aHJvd0dlbmVyaWNTUUxFeGNlcHRpb24oc0Vycm9yLCp0aGlzKTsKCX0KCS8vCXNldE9iamVjdCAocGFyYW1ldGVySW5kZXgsIHgsIHNxbFR5cGUsIDApOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRTaG9ydCggc2FsX0ludDMyIHBhcmFtZXRlckluZGV4LCBzYWxfSW50MTYgeCApIHRocm93KFNRTEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKewoJc2V0UGFyYW1ldGVyKHBhcmFtZXRlckluZGV4LGFkU21hbGxJbnQsc2l6ZW9mKHgpLHgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRCeXRlcyggc2FsX0ludDMyIHBhcmFtZXRlckluZGV4LCBjb25zdCBTZXF1ZW5jZTwgc2FsX0ludDggPiYgeCApIHRocm93KFNRTEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKewoJc2V0UGFyYW1ldGVyKHBhcmFtZXRlckluZGV4LGFkVmFyQmluYXJ5LHNpemVvZihzYWxfSW50OCkqeC5nZXRMZW5ndGgoKSx4KTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpzZXRDaGFyYWN0ZXJTdHJlYW0oIHNhbF9JbnQzMiAvKnBhcmFtZXRlckluZGV4Ki8sIGNvbnN0IFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6aW86OlhJbnB1dFN0cmVhbSA+JiAvKngqLywgc2FsX0ludDMyIC8qbGVuZ3RoKi8gKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIDo6ZGJ0b29sczo6dGhyb3dGZWF0dXJlTm90SW1wbGVtZW50ZWRFeGNlcHRpb24oICJYUGFyYW1ldGVyczo6c2V0Q2hhcmFjdGVyU3RyZWFtIiwgKnRoaXMgKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTQUxfQ0FMTCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OnNldEJpbmFyeVN0cmVhbSggc2FsX0ludDMyIHBhcmFtZXRlckluZGV4LCBjb25zdCBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmlvOjpYSW5wdXRTdHJlYW0gPiYgeCwgc2FsX0ludDMyIGxlbmd0aCApIHRocm93KFNRTEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKewoJaWYoeC5pcygpKQoJewoJCVNlcXVlbmNlPCBzYWxfSW50OCA+IGFEYXRhOwoJCXgtPnJlYWRCeXRlcyhhRGF0YSxsZW5ndGgpOwoJCXNldEJ5dGVzKHBhcmFtZXRlckluZGV4LGFEYXRhKTsKCX0KfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6Y2xlYXJQYXJhbWV0ZXJzKCAgKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbV9hTXV0ZXggKTsKCWNoZWNrRGlzcG9zZWQoT1N0YXRlbWVudF9CQVNFOjpyQkhlbHBlci5iRGlzcG9zZWQpOwoKCglpZihtX3BQYXJhbWV0ZXJzKQoJewoJCXNhbF9JbnQzMiBuQ291bnQgPSAwOwoJCW1fcFBhcmFtZXRlcnMtPmdldF9Db3VudCgmbkNvdW50KTsKCQlPTEVWYXJpYW50IGFWYWw7CgkJYVZhbC5zZXRFbXB0eSgpOwoJCWZvcihzYWxfSW50MzIgaT0wO2k8bkNvdW50OysraSkKCQl7CgkJCUFET1BhcmFtZXRlciogcFBhcmFtID0gTlVMTDsKCQkJbV9wUGFyYW1ldGVycy0+Z2V0X0l0ZW0oT0xFVmFyaWFudChpKSwmcFBhcmFtKTsKCQkJV3BBRE9QYXJhbWV0ZXIgYVBhcmFtKHBQYXJhbSk7CgkJCWlmKHBQYXJhbSkKCQkJewoJCQkJOjpydGw6Ok9VU3RyaW5nIHNQYXJhbSA9IGFQYXJhbS5HZXROYW1lKCk7CgkJCQlDSEVDS19SRVRVUk4oYVBhcmFtLlB1dFZhbHVlKGFWYWwpKTsKCQkJfQoJCX0KCQkJLy8JbV9wUGFyYW1ldGVycy0+RGVsZXRlKE9MRVZhcmlhbnQoaSkpOwoKCX0KfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpjbGVhckJhdGNoKCAgKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCS8vCWNsZWFyUGFyYW1ldGVycyggICk7CgkvLwltX2FCYXRjaExpc3QuZXJhc2UoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp2b2lkIFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6YWRkQmF0Y2goICkgdGhyb3coU1FMRXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKU2VxdWVuY2U8IHNhbF9JbnQzMiA+IFNBTF9DQUxMIE9QcmVwYXJlZFN0YXRlbWVudDo6ZXhlY3V0ZUJhdGNoKCAgKSB0aHJvdyhTUUxFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCXJldHVybiBTZXF1ZW5jZTwgc2FsX0ludDMyID4gKCk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBPUHJlcGFyZWRTdGF0ZW1lbnQ6OmFjcXVpcmUoKSB0aHJvdygpCnsKCU9TdGF0ZW1lbnRfQmFzZTo6YWNxdWlyZSgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgT1ByZXBhcmVkU3RhdGVtZW50OjpyZWxlYXNlKCkgdGhyb3coKQp7CglPU3RhdGVtZW50X0Jhc2U6OnJlbGVhc2UoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9QcmVwYXJlZFN0YXRlbWVudDo6cmVwbGFjZVBhcmFtZXRlck5vZGVOYW1lKE9TUUxQYXJzZU5vZGUqIF9wTm9kZSwKCQkJCQkJCQkJCQkJICBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9zRGVmYXVsdE5hbWUsCgkJCQkJCQkJCQkJCSAgc2FsX0ludDMyJiBfclBhcmFtZXRlckNvdW50KQp7CglzYWxfSW50MzIgbkNvdW50ID0gX3BOb2RlLT5jb3VudCgpOwoJZm9yKHNhbF9JbnQzMiBpPTA7aSA8IG5Db3VudDsrK2kpCgl7CgkJT1NRTFBhcnNlTm9kZSogcENoaWxkTm9kZSA9IF9wTm9kZS0+Z2V0Q2hpbGQoaSk7CgkJaWYoU1FMX0lTUlVMRShwQ2hpbGROb2RlLHBhcmFtZXRlcikgJiYgcENoaWxkTm9kZS0+Y291bnQoKSA9PSAxKQoJCXsKCQkJT1NRTFBhcnNlTm9kZSogcE5ld05vZGUgPSBuZXcgT1NRTFBhcnNlTm9kZSg6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiOiIpICxTUUxfTk9ERV9QVU5DVFVBVElPTiwwKTsKCQkJZGVsZXRlIHBDaGlsZE5vZGUtPnJlcGxhY2UocENoaWxkTm9kZS0+Z2V0Q2hpbGQoMCkscE5ld05vZGUpOwoJCQk6OnJ0bDo6T1VTdHJpbmcgc1BhcmFtZXRlck5hbWUgPSBfc0RlZmF1bHROYW1lOwoJCQlzUGFyYW1ldGVyTmFtZSArPSA6OnJ0bDo6T1VTdHJpbmc6OnZhbHVlT2YoKytfclBhcmFtZXRlckNvdW50KTsKCQkJcENoaWxkTm9kZS0+YXBwZW5kKG5ldyBPU1FMUGFyc2VOb2RlKCBzUGFyYW1ldGVyTmFtZSxTUUxfTk9ERV9OQU1FLDApKTsKCQl9CgkJZWxzZQoJCQlyZXBsYWNlUGFyYW1ldGVyTm9kZU5hbWUocENoaWxkTm9kZSxfc0RlZmF1bHROYW1lLF9yUGFyYW1ldGVyQ291bnQpOwoKCX0KfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCgo=