I2luY2x1ZGUgPENvcHlyaWdodC5oPgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBndE1pc2MuYwoqCiogREVTQ1JJUFRJT046CiogICAgICAgQVBJIGRlZmluaXRpb25zIGZvciBJcCBNYXBwaW5nIFRhYmxlCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgRUVQUk9NIGFjY2VzcwoqICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNjcmF0Y2ggYW5kIE1pc2MgQ29udHJvbAoqIERFUEVOREVOQ0lFUzoKKgoqIEZJTEUgUkVWSVNJT04gTlVNQkVSOgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgPG1zQXBpLmg+CiNpbmNsdWRlIDxndFNlbS5oPgojaW5jbHVkZSA8Z3RId0NudGwuaD4KI2luY2x1ZGUgPGd0RHJ2U3dSZWdzLmg+CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0VXNlSXBNYXBwaW5nVGFibGUKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBUaGlzIEFQSSBzZXQgdG8gdXNlIElQIEZyYW1lIFByaW9yaXRpZXMgZnJvbSB0aGlzIHRhYmxlLiAKKiAgICAgICAgU2V0IEdUX1RSVUU6ICBUaGUgSVBfRlBSSSBkYXRhIGluIHRoaXMgdGFibGUgaXMgdXNlZCBhcyB0aGUgZnJhbWWScyAKKiAgICAgICAgICAgIGluaXRpYWwgSVBfRlBSSS4KKiAgICAgICAgU2V0IEdUX0ZBTFNFOiBUaGUgSVBfRlBSSSBkYXRhIGluIHRoaXMgdGFibGUgaXMgaWdub3JlZC4gSW5zdGVhZCB0aGUgCiogICAgICAgICAgICBmcmFtZZJzIGluaXRpYWwgSVBfRlBSSSBpcyBnZW5lcmF0ZWQgYnkgdXNpbmcgdGhlIGZyYW1lknMgSVBfUVBSSQoqICAgICAgICAgICAgYXMgdGhlIElQX0ZQUkmScyB1cHBlciB0d28gYml0cywgYW5kIHRoZSBJUF9GUFJJknMgbG93ZXN0IGJpdCBjb21lcyAKKiAgICAgICAgICAgIGZyb20gYml0IDAgb2YgdGhlIGZyYW1lknMgc291cmNlIHBvcnSScyBEZWZhdWx0IFBSSSAoUG9ydCBvZmZzZXQgMHgwNykuCioKKiBJTlBVVFM6CiogICAgICAgIGVuICAgIC0gW0dUX1RSVUVdIC8gW0dUX0ZBTFNFXQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRVc2VJcE1hcHBpbmdUYWJsZQooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9CT09MICAgICAgICAgICAgZW4KKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNTZXRVc2VJcE1hcHBpbmdUYWJsZSBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfSVBfTUFQUElOR19UQUJMRSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgZGF0YSA9IChlbj09R1RfVFJVRSk/MTowOwoKICAgIHJldFZhbCA9IGh3U2V0R2xvYmFsUmVnRmllbGQoZGV2LFFEX1JFR19JUF9NQVBQSU5HX1RBQkxFLDE0LDEsZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICByZXR1cm4gR1RfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRVc2VJcE1hcHBpbmdUYWJsZQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFRoaXMgQVBJIGdldCB0byB1c2UgSVAgRnJhbWUgUHJpb3JpdGllcyBmcm9tIHRoaXMgdGFibGUuIAoqICAgICAgICBTZXQgR1RfVFJVRTogIFRoZSBJUF9GUFJJIGRhdGEgaW4gdGhpcyB0YWJsZSBpcyB1c2VkIGFzIHRoZSBmcmFtZZJzIAoqICAgICAgICAgICAgaW5pdGlhbCBJUF9GUFJJLgoqICAgICAgICBTZXQgR1RfRkFMU0U6IFRoZSBJUF9GUFJJIGRhdGEgaW4gdGhpcyB0YWJsZSBpcyBpZ25vcmVkLiBJbnN0ZWFkIHRoZSAKKiAgICAgICAgICAgIGZyYW1lknMgaW5pdGlhbCBJUF9GUFJJIGlzIGdlbmVyYXRlZCBieSB1c2luZyB0aGUgZnJhbWWScyBJUF9RUFJJCiogICAgICAgICAgICBhcyB0aGUgSVBfRlBSSZJzIHVwcGVyIHR3byBiaXRzLCBhbmQgdGhlIElQX0ZQUkmScyBsb3dlc3QgYml0IGNvbWVzIAoqICAgICAgICAgICAgZnJvbSBiaXQgMCBvZiB0aGUgZnJhbWWScyBzb3VyY2UgcG9ydJJzIERlZmF1bHQgUFJJIChQb3J0IG9mZnNldCAweDA3KS4KKgoqIElOUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIE9VVFBVVFM6CiogICAgICAgIGVuICAgIC0gW0dUX1RSVUVdIC8gW0dUX0ZBTFNFXQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldFVzZUlwTWFwcGluZ1RhYmxlCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX0JPT0wgICAgICAgICAgICAqZW4KKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRVc2VJcE1hcHBpbmdUYWJsZSBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfSVBfTUFQUElOR19UQUJMRSkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgoKICAgIHJldFZhbCA9IGh3R2V0R2xvYmFsUmVnRmllbGQoZGV2LFFEX1JFR19JUF9NQVBQSU5HX1RBQkxFLDE0LDEsJmRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgKmVuPSAoZGF0YT09MSk/R1RfVFJVRTpHVF9GQUxTRTsKCiAgICByZXR1cm4gR1RfT0s7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0SXBNYXBwaW5nUHJpbwoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFNldCBJUHY0IGFuZCBJUHY2IEZyYW1lIFByaW9yaXR5IE1hcHBpbmcsIGFuZCAKKiAgICAgICAgSVB2NCBhbmQgSVB2NiBRdWV1ZSBQcmlvcml0eSBNYXBwaW5nLgoqICAgICAgIFRoZSBpcEZwcmkgdmFsdWUgaXMgdXNlZCBhcyB0aGUgZnJhbWUncyBpbml0aWFsIEZQUkkgd2hlbiB0aGUgZnJhbWUgaXMgCiogICAgICAgIGFuIElQdjQgb3IgYW4gSVB2NiBmcmFtZSwgYW5kIHRoZSBwb3J0knMgSW5pdGlhbFByaSAoUG9ydCBvZmZzZXQgMHgwNCkgCiogICAgICAgIGlzIGNvbmZpZ3VyZWQgdG8gdXNlIElQIEZQcmmScy4KKiAgICAgICBUaGUgaXBRcHJpIHZhbHVlIGlzIHVzZWQgYXMgdGhlIGZyYW1lknMgaW5pdGlhbCBRUFJJIHdoZW4gdGhlIGZyYW1lIGlzIAoqICAgICAgICBhbiBJUHY0IG9yIGFuIElQdjYgZnJhbWUsIGFuZCB0aGUgcG9ydJJzIEluaXRpYWxQcmkgYW5kIFRhZ0lmQm90aCAKKiAgICAgICAgcmVnaXN0ZXJzIChQb3J0IG9mZnNldCAweDA0KSBhcmUgY29uZmlndXJlZCB0byB1c2UgSVAgUVByaZJzLgoqCiogSU5QVVRTOgoqICAgICAgICBwb2ludCAtIFBvaW50ZXIgdG8gdGhlIElwIE1hcHBpbmcgVGFibGUuCiogICAgICAgICAgICAgICAgMCAtIDB4M2Y7CiogICAgICAgIGlwRnByaSAtICBUaGUgdmFsdWUgaXMgMCAtIDcKKiAgICAgICAgaXBRcHJpIC0gIFRoZSB2YWx1ZSBpcyAwIC0gMy4KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0SXBNYXBwaW5nUHJpbwooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICAgICBwb2ludCwKICAgIElOICBHVF9VOCAgICAgICAgICAgIGlwRnByaSwKICAgIElOICBHVF9VOCAgICAgICAgICAgIGlwUXByaQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTE2ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c1NldElwTWFwcGluZ1ByaW8gQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX0lQX01BUFBJTkdfVEFCTEUpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIGlmICgocG9pbnQ+MHgzZil8fChpcEZwcmk+Nyl8fChpcFFwcmk+MykpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIGd0U2VtVGFrZShkZXYsZGV2LT50YmxSZWdzU2VtLE9TX1dBSVRfRk9SRVZFUik7CgogICAgLyogV2FpdCB1bnRpbCB0aGUgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGlzIHJlYWR5LiAqLwojaWZkZWYgR1RfUk1HTVRfQUNDRVNTCiAgICB7CiAgICAgIEhXX0RFVl9SRUdfQUNDRVNTIHJlZ0FjY2VzczsKCiAgICAgIHJlZ0FjY2Vzcy5lbnRyaWVzID0gMTsKICAKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmNtZCA9IEhXX1JFR19XQUlUX1RJTExfMDsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmFkZHIgPSBDQUxDX1NNSV9ERVZfQUREUihkZXYsIDAsIEdMT0JBTF9SRUdfQUNDRVNTKTsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLnJlZyA9IFFEX1JFR19JUF9NQVBQSU5HX1RBQkxFOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uZGF0YSA9IDE1OwogICAgICByZXRWYWwgPSBod0FjY2Vzc011bHRpUmVncyhkZXYsICZyZWdBY2Nlc3MpOwogICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgIHsKICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dnR1UmVnc1NlbSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgfQogICAgfQojZWxzZQogICAgICAgZGF0YSA9IDE7CiAgICB3aGlsZShkYXRhID09IDEpCiAgICAgICB7CiAgICAgICAgcmV0VmFsID0gaHdHZXRHbG9iYWxSZWdGaWVsZChkZXYsUURfUkVHX0lQX01BUFBJTkdfVEFCTEUsMTUsMSwmZGF0YSk7CiAgICAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgIHsKICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwogICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgIH0KICAgIH0KI2VuZGlmCgogICAgZGF0YSA9ICgoKGlwRnByaSY3KTw8NCkgfCAoaXBRcHJpJjMpKTsKICAgIGRhdGEgfD0gICgoR1RfVTE2KSgoMSA8PCAxNSkgfCAocG9pbnQgPDwgOCkpKTsKCiAgICByZXRWYWwgPSBod1dyaXRlR2xvYmFsUmVnKGRldiwgUURfUkVHX0lQX01BUFBJTkdfVEFCTEUsIGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCgogICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwoKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldElwTWFwcGluZ1ByaW8KKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgSVB2NCBhbmQgSVB2NiBGcmFtZSBQcmlvcml0eSBNYXBwaW5nLCBhbmQgCiogICAgICAgIElQdjQgYW5kIElQdjYgUXVldWUgUHJpb3JpdHkgTWFwcGluZy4KKiAgICAgICBUaGUgaXBGcHJpIHZhbHVlIGlzIHVzZWQgYXMgdGhlIGZyYW1lJ3MgaW5pdGlhbCBGUFJJIHdoZW4gdGhlIGZyYW1lIGlzIAoqICAgICAgICBhbiBJUHY0IG9yIGFuIElQdjYgZnJhbWUsIGFuZCB0aGUgcG9ydJJzIEluaXRpYWxQcmkgKFBvcnQgb2Zmc2V0IDB4MDQpIAoqICAgICAgICBpcyBjb25maWd1cmVkIHRvIHVzZSBJUCBGUHJpknMuCiogICAgICAgIFRoZSBpcFFwcmkgdmFsdWUgaXMgdXNlZCBhcyB0aGUgZnJhbWWScyBpbml0aWFsIFFQUkkgd2hlbiB0aGUgZnJhbWUgaXMgCiogICAgICAgIGFuIElQdjQgb3IgYW4gSVB2NiBmcmFtZSwgYW5kIHRoZSBwb3J0knMgSW5pdGlhbFByaSBhbmQgVGFnSWZCb3RoIAoqICAgICAgICByZWdpc3RlcnMgKFBvcnQgb2Zmc2V0IDB4MDQpIGFyZSBjb25maWd1cmVkIHRvIHVzZSBJUCBRUHJpknMuCioKKiBJTlBVVFM6CiogICAgICAgIHBvaW50IC0gUG9pbnRlciB0byB0aGUgSXAgTWFwcGluZyBUYWJsZS4KKiAgICAgICAgICAgICAgICAwIC0gMHgzZjsKKgoqIE9VVFBVVFM6CiogICAgICAgIGlwRnByaSAtICBUaGUgdmFsdWUgaXMgMCAtIDcKKiAgICAgICAgaXBRcHJpIC0gIFRoZSB2YWx1ZSBpcyAwIC0gMy4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lLgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzR2V0SXBNYXBwaW5nUHJpbwooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICAgICBwb2ludCwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqaXBGcHJpLAogICAgT1VUICBHVF9VOCAgICAgICAgICAgICppcFFwcmkKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1UxNiAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRJcE1hcHBpbmdQcmlvIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9JUF9NQVBQSU5HX1RBQkxFKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBpZiAocG9pbnQgPiAweDNmKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfQkFEX1BBUkFNXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgIH0KCiAgICBndFNlbVRha2UoZGV2LGRldi0+dGJsUmVnc1NlbSxPU19XQUlUX0ZPUkVWRVIpOwoKI2lmZGVmIEdUX1JNR01UX0FDQ0VTUwogICAgewogICAgICBIV19ERVZfUkVHX0FDQ0VTUyByZWdBY2Nlc3M7CgogICAgICByZWdBY2Nlc3MuZW50cmllcyA9IDI7CiAgCiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5jbWQgPSBIV19SRUdfV0FJVF9USUxMXzA7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5hZGRyID0gQ0FMQ19TTUlfREVWX0FERFIoZGV2LCAwLCBHTE9CQUxfUkVHX0FDQ0VTUyk7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5yZWcgPSBRRF9SRUdfSVBfTUFQUElOR19UQUJMRTsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmRhdGEgPSAxNTsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzFdLmNtZCA9IEhXX1JFR19SRUFEOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMV0uYWRkciA9IENBTENfU01JX0RFVl9BRERSKGRldiwgMCwgR0xPQkFMX1JFR19BQ0NFU1MpOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMV0ucmVnID0gUURfUkVHX0lQX01BUFBJTkdfVEFCTEU7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFsxXS5kYXRhID0gMDsKICAgICAgcmV0VmFsID0gaHdBY2Nlc3NNdWx0aVJlZ3MoZGV2LCAmcmVnQWNjZXNzKTsKICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICB7CiAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnZ0dVJlZ3NTZW0pOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgIH0KICAgICAgZGF0YSA9IHFkTG9uZzJTaG9ydChyZWdBY2Nlc3MucndfcmVnX2xpc3RbMV0uZGF0YSk7CiAgICB9CiNlbHNlCiAgICBkbyB7CiAgICAgICAgcmV0VmFsID0gaHdSZWFkR2xvYmFsUmVnKGRldiwgUURfUkVHX0lQX01BUFBJTkdfVEFCTEUsICZkYXRhKTsKICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgICAgewogICAgICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnRibFJlZ3NTZW0pOwogICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgIH0KICAgIH0gd2hpbGUgKGRhdGEmMHg4MDAwKTsKI2VuZGlmCgoKICAgICppcEZwcmkgPSAoZGF0YSA+PiA0KSAmIDc7CiAgICAqaXBRcHJpID0gKGRhdGEpICYgMzsKCiAgICBndFNlbUdpdmUoZGV2LGRldi0+dGJsUmVnc1NlbSk7CgogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgcmV0dXJuIEdUX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBlZXByb21PcGVyYXRpb25QZXJmb3JtCioKKiBERVNDUklQVElPTjoKKiAgICAgICBUaGlzIGZ1bmN0aW9uIGFjY2Vzc2VzIEVFUFJPTSBDb21tYW5kIFJlZ2lzdGVyIGFuZCBEYXRhIFJlZ2lzdGVyLgoqICAgICAgIFRoZSBkZXZpY2Ugc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBFRVBST00gCiogICAgICAgICAgICBvcGVyYXRpb25zCiogICAgICAgICAgICBHVF9FRVBST01fTk9fT1AgPSBObyBPcGVyYXRpb24KKiAgICAgICAgICAgIEdUX0VFUFJPTV9XUklURV9EQVRBID0gV3JpdGUgRUVQUk9NIGF0IEFkZHIuCiogICAgICAgICAgICBHVF9FRVBST01fUkVBRF9EQVRBID0gUmVhZCBFRVBST00gZnJvbSBBZGRyLgoqICAgICAgICAgICAgR1RfRUVQUk9NX1JFU1RBUlQgPSBSZXN0YXJ0IFJlZ2lzdGVyIExvYWRlciBleGVjdXRpb24gYXQgQWRkciAKKiAgICAgICAgICAgICAgICAoZWVwcm9tRGF0YSA9IGRvbpJ0IGNhcmUgaW4gdGhpcyBjYXNlKQoqICAgICAgICAgICAgR1RfRUVQUk9NX0hBTFQgPSBIYWx0IChzdG9wIGV4ZWN1dGluZyB0aGUgRUVQUk9NIGlmIGl0cyBub3QgYWxyZWFkeSAKKiAgICAgICAgICAgICAgICBzdG9wcGVkKQoqCiogSU5QVVRTOgoqICAgICAgIGVlcHJvbU9wICAgICAgLSBFRVBST00gT3Bjb2RlLgoqICAgICAgIGVlcHJvbURhdGEgICAgLSBEYXRhIHRvIGJlIHdyaXR0ZW4gdG8gdGhlIEVFUFJPTSAKKgoqIE9VVFBVVFM6CiogICAgICAgZWVwcm9tRGF0YSAgICAtIERhdGEgdGhhdCB3YXMgcmVhZCBiYWNrIGZyb20gdGhlIEVFUFJPTS4gCioKQ29tbWFuZCByZWdpc3RlciBhYm92ZS4KKgoqIFJFVFVSTlM6CiogICAgICAgR1RfT0sgb24gc3VjY2VzcywKKiAgICAgICBHVF9GQUlMIG90aGVyd2lzZS4KKiAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCioKKiBDT01NRU5UUzoKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgR1RfU1RBVFVTIGVlcHJvbU9wZXJhdGlvblBlcmZvcm0KKAogICAgSU4gICAgR1RfUURfREVWICAgICAgICAgICAgICpkZXYsCiAgICBJTiAgICBHVF9FRVBST01fT1BFUkFUSU9OICAgIGVlcHJvbU9wLAogICAgSU5PVVQgR1RfRUVQUk9NX09QX0RBVEEgICAgICAgICpvcERhdGEKKQp7CiAgICBHVF9TVEFUVVMgICAgICAgcmV0VmFsOyAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlICovCiAgICBHVF9VMTYgICAgICAgICAgZGF0YTsgICAgIC8qIHRlbXBvcmFyeSBEYXRhIHN0b3JhZ2UgKi8KICAgIERCR19JTkZPKCgiZWVwcm9tT3BlcmF0aW9uUGVyZm9ybSBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfRUVQUk9NKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBpZiAoZWVwcm9tT3A+R1RfRUVQUk9NX0hBTFQpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9CQURfUEFSQU1cbiIpKTsKICAgICAgICByZXR1cm4gR1RfQkFEX1BBUkFNOwogICAgfQoKICAgIGd0U2VtVGFrZShkZXYsZGV2LT5lZXByb21SZWdzU2VtLE9TX1dBSVRfRk9SRVZFUik7CgoKICAgIC8qIFdhaXQgdW50aWwgdGhlIGVlcHJvbSBpbiByZWFkeS4gKi8KI2lmZGVmIEdUX1JNR01UX0FDQ0VTUwogICAgewogICAgICBIV19ERVZfUkVHX0FDQ0VTUyByZWdBY2Nlc3M7CgogICAgICByZWdBY2Nlc3MuZW50cmllcyA9IDE7CiAgCiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5jbWQgPSBIV19SRUdfV0FJVF9USUxMXzA7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5hZGRyID0gQ0FMQ19TTUlfREVWX0FERFIoZGV2LCAwLCBHTE9CQUwyX1JFR19BQ0NFU1MpOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0ucmVnID0gUURfUkVHX0VFUFJPTV9DT01NQU5EOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uZGF0YSA9IDE1OwogICAgICByZXRWYWwgPSBod0FjY2Vzc011bHRpUmVncyhkZXYsICZyZWdBY2Nlc3MpOwogICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgIHsKICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dnR1UmVnc1NlbSk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgfQogICAgfQojZWxzZQogICAgZGF0YSA9IDE7CiAgICB3aGlsZShkYXRhID09IDEpCiAgICB7CiAgICAgICAgcmV0VmFsID0gaHdHZXRHbG9iYWwyUmVnRmllbGQoZGV2LFFEX1JFR19FRVBST01fQ09NTUFORCwxNSwxLCZkYXRhKTsKICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgewogICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CiAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgfQogICAgfQojZW5kaWYKCgogICAgLyogU2V0IHRoZSBFRVBST00gT3BlcmF0aW9uIHJlZ2lzdGVyICovCiAgICBzd2l0Y2ggKGVlcHJvbU9wKQogICAgewogICAgICAgIGNhc2UgR1RfRUVQUk9NX1dSSVRFX0RBVEE6CiAgICAgICAgICAgIHJldFZhbCA9IGh3R2V0R2xvYmFsMlJlZ0ZpZWxkKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsMTAsMSwmZGF0YSk7CiAgICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZGF0YT09MCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICAgICAgREJHX0lORk8oKCJFRVBST00gaXMgbm90IHdyaXRhYmxlbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBHVF9GQUlMOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXRWYWwgPSBod0dldEdsb2JhbDJSZWdGaWVsZChkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELDExLDEsJmRhdGEpOwogICAgICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRhdGE9PTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIERCR19JTkZPKCgiRUVQUk9NIExvYWRlciBpcyBydW5uaW5nIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRhdGEgPSAoR1RfVTE2KW9wRGF0YS0+ZWVwcm9tRGF0YTsKICAgICAgICAgICAgcmV0VmFsID0gaHdXcml0ZUdsb2JhbDJSZWcoZGV2LFFEX1JFR19FRVBST01fREFUQSxkYXRhKTsKICAgICAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBkYXRhID0gKEdUX1UxNikoKDEgPDwgMTUpIHwgKEdUX0VFUFJPTV9XUklURV9EQVRBIDw8IDEyKSB8IAogICAgICAgICAgICAgICAgICAgIChvcERhdGEtPmVlcHJvbUFkZHIgJiAweEZGKSk7CiAgICAgICAgICAgIHJldFZhbCA9IGh3V3JpdGVHbG9iYWwyUmVnKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsZGF0YSk7CiAgICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBHVF9FRVBST01fUkVBRF9EQVRBOgogICAgICAgICAgICByZXRWYWwgPSBod0dldEdsb2JhbDJSZWdGaWVsZChkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELDExLDEsJmRhdGEpOwogICAgICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRhdGE9PTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIERCR19JTkZPKCgiRUVQUk9NIExvYWRlciBpcyBydW5uaW5nIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIEdUX0ZBSUw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRhdGEgPSAoR1RfVTE2KSgoMSA8PCAxNSkgfCAoR1RfRUVQUk9NX1JFQURfREFUQSA8PCAxMikgfCAKICAgICAgICAgICAgICAgICAgICAob3BEYXRhLT5lZXByb21BZGRyICYgMHhGRikpOwogICAgICAgICAgICByZXRWYWwgPSBod1dyaXRlR2xvYmFsMlJlZyhkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELGRhdGEpOwogICAgICAgICAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIAojaWZkZWYgR1RfUk1HTVRfQUNDRVNTCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBIV19ERVZfUkVHX0FDQ0VTUyByZWdBY2Nlc3M7CgogICAgICAgICAgICAgIHJlZ0FjY2Vzcy5lbnRyaWVzID0gMTsKICAKICAgICAgICAgICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0uY21kID0gSFdfUkVHX1dBSVRfVElMTF8wOwogICAgICAgICAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5hZGRyID0gQ0FMQ19TTUlfREVWX0FERFIoZGV2LCAwLCBHTE9CQUwyX1JFR19BQ0NFU1MpOwogICAgICAgICAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5yZWcgPSBRRF9SRUdfRUVQUk9NX0NPTU1BTkQ7CiAgICAgICAgICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmRhdGEgPSAxNTsKICAgICAgICAgICAgICByZXRWYWwgPSBod0FjY2Vzc011bHRpUmVncyhkZXYsICZyZWdBY2Nlc3MpOwogICAgICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dnR1UmVnc1NlbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQojZWxzZQogICAgICAgICAgICBkYXRhID0gMTsKICAgICAgICAgICAgd2hpbGUoZGF0YSA9PSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXRWYWwgPSBod0dldEdsb2JhbDJSZWdGaWVsZChkZXYsUURfUkVHX0VFUFJPTV9DT01NQU5ELDE1LDEsJmRhdGEpOwogICAgICAgICAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT5lZXByb21SZWdzU2VtKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICAKCiAgICAgICAgICAgIHJldFZhbCA9IGh3UmVhZEdsb2JhbDJSZWcoZGV2LFFEX1JFR19FRVBST01fREFUQSwmZGF0YSk7CiAgICAgICAgICAgIG9wRGF0YS0+ZWVwcm9tRGF0YSA9IChHVF9VMzIpZGF0YTsKCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEdUX0VFUFJPTV9SRVNUQVJUOgogICAgICAgICAgICBkYXRhID0gKEdUX1UxNikoKDEgPDwgMTUpIHwgKEdUX0VFUFJPTV9SRVNUQVJUIDw8IDEyKSB8IAogICAgICAgICAgICAgICAgICAgIChvcERhdGEtPmVlcHJvbUFkZHIgJiAweEZGKSk7CiAgICAgICAgICAgIHJldFZhbCA9IGh3V3JpdGVHbG9iYWwyUmVnKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsZGF0YSk7CiAgICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEdUX0VFUFJPTV9IQUxUOgogICAgICAgICAgICBkYXRhID0gKEdUX1UxNikoKDEgPDwgMTUpIHwgKEdUX0VFUFJPTV9IQUxUIDw8IDEyKSB8IAogICAgICAgICAgICAgICAgICAgIChvcERhdGEtPmVlcHJvbUFkZHIgJiAweEZGKSk7CiAgICAgICAgICAgIHJldFZhbCA9IGh3V3JpdGVHbG9iYWwyUmVnKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsZGF0YSk7CiAgICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPmVlcHJvbVJlZ3NTZW0pOwogICAgICAgICAgICByZXR1cm4gR1RfRkFJTDsKICAgIH0KCiAgICBndFNlbUdpdmUoZGV2LGRldi0+ZWVwcm9tUmVnc1NlbSk7CiAgICByZXR1cm4gR1RfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNSZWFkRWVwcm9tCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgUmVhZCBFRVBST00gZnJvbSBFRVBST02ScyBhZGRyZXNzIHdoZXJlIHRoZSBFRU9wIGlzIHBlcmZvcm1lZC4KKgoqIElOUFVUUzoKKiAgICAgICAgYWRkciAtIEVFUFJPTSBBZGRyZXNzLiAKKgoqIE9VVFBVVFM6CiogICAgICAgIGRhdGEgLSAgRGF0YSB0aGF0IHdhcyByZWFkIGJhY2sgZnJvbSB0aGUgRUVQUk9NLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1JlYWRFZXByb20KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgYWRkciwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqZGF0YQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfRUVQUk9NX09QRVJBVElPTiAgICBlZXByb21PcDsKICAgIEdUX0VFUFJPTV9PUF9EQVRBICAgIG9wRGF0YTsKIAogICAgZWVwcm9tT3AgPSBHVF9FRVBST01fUkVBRF9EQVRBOwogICAgb3BEYXRhLmVlcHJvbUFkZHIgPSBhZGRyOwoKICAgIHJldFZhbCA9IGVlcHJvbU9wZXJhdGlvblBlcmZvcm0oZGV2LGVlcHJvbU9wLCZvcERhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICByZXR1cm4gcmV0VmFsOwogICAgfQogICAgKmRhdGEgPSAoR1RfVTgpb3BEYXRhLmVlcHJvbURhdGE7CiAgICByZXR1cm4gR1RfT0s7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNXcml0ZUVlcHJvbQoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFdyaXRlIEVFUFJPTSBhdCB0aGUgRUVQUk9NknMgYWRkcmVzcyB3aGVyZSB0aGUgRUVPcCBpcyBwZXJmb3JtZWQuCioKKiBJTlBVVFM6CiogICAgICAgIGFkZHIgLSBFRVBST00gQWRkcmVzcy4gCiogICAgICAgIGRhdGEgLSBEYXRhIHRvIGJlIHdyaXR0ZW4gdG8gdGhlIEVFUFJPTQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNXcml0ZUVlcHJvbQooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VMzIgICAgICAgICAgICBhZGRyLAogICAgSU4gIEdUX1U4ICAgICAgICAgICAgZGF0YQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfRUVQUk9NX09QRVJBVElPTiAgICBlZXByb21PcDsKICAgIEdUX0VFUFJPTV9PUF9EQVRBICAgIG9wRGF0YTsKIAogICAgZWVwcm9tT3AgPSBHVF9FRVBST01fV1JJVEVfREFUQTsKICAgIG9wRGF0YS5lZXByb21BZGRyID0gYWRkcjsKICAgIG9wRGF0YS5lZXByb21EYXRhID0gZGF0YTsKCiAgICByZXRWYWwgPSBlZXByb21PcGVyYXRpb25QZXJmb3JtKGRldixlZXByb21PcCwmb3BEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNSZXN0YXJ0RWVwcm9tCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgUmVzdGFydCBSZWdpc3RlciBMb2FkZXIgZXhlY3V0aW9uIGF0IHRoZSBFRVBST02ScyBhZGRyZXNzIHdoZXJlIHRoZSBFRU9wIAoqICAgICAgICBpcyBwZXJmb3JtZWQKKgoqIElOUFVUUzoKKiAgICAgICAgYWRkciAtIEVFUFJPTSBBZGRyZXNzLiAuCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1Jlc3RhcnRFZXByb20KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgYWRkcgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfRUVQUk9NX09QRVJBVElPTiAgICBlZXByb21PcDsKICAgIEdUX0VFUFJPTV9PUF9EQVRBICAgIG9wRGF0YTsKIAogICAgZWVwcm9tT3AgPSBHVF9FRVBST01fUkVTVEFSVDsKICAgIG9wRGF0YS5lZXByb21BZGRyID0gYWRkcjsKCiAgICByZXRWYWwgPSBlZXByb21PcGVyYXRpb25QZXJmb3JtKGRldixlZXByb21PcCwmb3BEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNIYWx0RWVwcm9tCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgSGFsdCAoc3RvcCBleGVjdXRpbmcgdGhlIEVFUFJPTSBpZiBpdHMgbm90IGFscmVhZHkgc3RvcHBlZCkKKgoqIElOUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzSGFsdEVlcHJvbQooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfRUVQUk9NX09QRVJBVElPTiAgICBlZXByb21PcDsKICAgIEdUX0VFUFJPTV9PUF9EQVRBICAgIG9wRGF0YTsKIAogICAgZWVwcm9tT3AgPSBHVF9FRVBST01fSEFMVDsKCiAgICByZXRWYWwgPSBlZXByb21PcGVyYXRpb25QZXJmb3JtKGRldixlZXByb21PcCwgICZvcERhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgewogICAgICByZXR1cm4gcmV0VmFsOwogICAgfQogICAgcmV0dXJuIEdUX09LOwoKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldFN0RWVwcm9tCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgR2V0IEVFUFJPTSBzdGF0dXMuIFRoZXkgYXJlIFJlZ2lzdGVyIExvYWRlciBSdW5uaW5nIHN0YXR1cyBhbmQgRUVQUk9NIAoqICAgICAgICBXcml0ZSBFbmFibGUgc3RhdHVzCiogICAgICAgIHJ1blN0IGlzIEdUX1RSVUU6IFJlZ2lzdGVyIExvYWRlciBSdW5uaW5nLCB3aGVuZXZlciB0aGUgcmVnaXN0ZXIgbG9hZGVyIAoqICAgICAgICAgICAgaXMgYnVzeSBleGVjdXRpbmcgdGhlIGluc3RydWN0aW9ucyBjb250YWluZWQgaW4gdGhlIEVFUFJPTS4KKiAgICAgICAgd3JpdGVFbiBpcyBHVF9UUlVFOiBFRVBST00gV3JpdGUgRW5hYmxlLCB0aGF0IGluZGljYXRlcyB0aGF0IHdyaXRpbmcgdG8gCiogICAgICAgICAgICB0aGUgRUVQUk9NIGlzIHBvc3NpYmxlLiAKKiAgICAgICAgd3JpdGVFbiBpcyBHVF9GQUxTRTogdGhlIFdyaXRlIEVFUFJPTSBFRU9wIGFib3ZlIHdpbGwgbm90IGRvIGFueXRoaW5nLgoqICAgICAgICAgICAgVGhpcyByZWZsZWN0cyB0aGUgdmFsdWUgb2YgdGhlIEVFX1dFIGNvbmZpZ3VyYXRpb24gcGluIGFmdGVyIFJlc2V0LgoqCiogSU5QVVRTOgoqICAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICAgcnVuU3QgICAtICAgW0dUX1RSVUVdIC8gW0dUX0ZBTFNFKQoqICAgICAgICB3cml0ZUVuIC0gICBbR1RfVFJVRV0gLyBbR1RfRkFMU0UpCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzR2V0U3RFZXByb20KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBPVVQgR1RfQk9PTCAgICAgICAgICAgICp3cml0ZUVuLAogICAgT1VUIEdUX0JPT0wgICAgICAgICAgICAqcnVuU3QKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1UxNiAgICAgIGRhdGE7ICAgICAgICAgICAgIC8qIHRlbXBvcmFyeSBEYXRhIHN0b3JhZ2UgKi8KIAogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfRUVQUk9NKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICByZXRWYWwgPSBod1JlYWRHbG9iYWwyUmVnKGRldixRRF9SRUdfRUVQUk9NX0NPTU1BTkQsICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgIHsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKCiAgICAqcnVuU3QgICA9IChkYXRhJkdUX0VFUFJPTV9PUF9TVF9SVU5OSU5HX01BU0spP0dUX1RSVUU6R1RfRkFMU0U7CiAgICAqd3JpdGVFbiA9IChkYXRhJkdUX0VFUFJPTV9PUF9TVF9XUklURV9FTl9NQVNLKT9HVF9UUlVFOkdUX0ZBTFNFOwoKICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBTZXQgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGRhdGEgdG8gdGhlIFNjcmF0Y2ggYW5kIE1pc2MgQ29udHJvbCByZWdpc3Rlci4gCiogICAgICAgIFRoZSByZWdpc3RlcnMgb2YgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGFyZS4KKiAgICAgICAgICAgICAgICBTY3JhdGNoIEJ5dGUgMAoqICAgICAgICAgICAgICAgIFNjcmF0Y2ggQnl0ZSAxCiogICAgICAgICAgICAgICAgR1BJTyBDb25maWd1cmF0aW9uCiogICAgICAgICAgICAgICAgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UKKiAgICAgICAgICAgICAgICBHUElPIERpcmVjdGlvbgoqICAgICAgICAgICAgICAgIEdQSU8gRGF0YQoqICAgICAgICAgICAgICAgIENPTkZJRyBEYXRhIDAKKiAgICAgICAgICAgICAgICBDT05GSUcgRGF0YSAxCiogICAgICAgICAgICAgICAgQ09ORklHIERhdGEgMgoqICAgICAgICAgICAgICAgIENPTkZJRyBEYXRhIDMKKiAgICAgICAgICAgICAgICBTeW5jRSAmIFRBSUNMSzEyNZJzIERyaXZlCiogICAgICAgICAgICAgICAgUDWScyAmIENMSzEyNZJzIENsb2NrIERyaXZlCiogICAgICAgICAgICAgICAgUDaScyBDbG9jayBEcml2ZQoqICAgICAgICAgICAgICAgIEVFUFJPTSBQYWQgZHJpdmUKKgoqIElOUFVUUzoKKiAgICAgICAgcG9pbnQgLSBQb2ludGVyIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjLiBDb250cm9sIHJlZ2lzdGVyLgoqICAgICAgICBkYXRhICAtIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgZGF0YSB3cml0dGVuIHRvIHRoZSByZWdpc3RlciAKKiAgICAgICAgICAgICAgICBwb2ludGVkIHRvIGJ5IHRoZSBwb2ludCBhYm92ZS4KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0U2NyYXRjaE1pc2NDdHJsCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX1UzMiAgICAgICAgICAgIHBvaW50LAogICAgSU4gIEdUX1U4ICAgICAgICAgICAgZGF0YQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgSU4gIEdUX1UxNiAgICAgICAgICAgIHRtcERhdGE7CgogICAgaWYgKHBvaW50ID4gR1RfU0NSQVRfTUlTQ19SRUdfTUFYKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfQkFEX1BBUkFNXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgIH0KCiAgICBpZiAoZGF0YSAmMHhmZmZmZmYwMCkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgZ3RTZW1UYWtlKGRldixkZXYtPnRibFJlZ3NTZW0sT1NfV0FJVF9GT1JFVkVSKTsKCiAgICAvKiBwcm9ncmFtIFFvUyBXZWlnaHQgVGFibGUsIDQgc2VxdWVuY2VzIGF0IGEgdGltZSAqLwoKICAgIC8qIFdhaXQgdW50aWwgdGhlIFNjcmF0Y2ggYW5kIE1pc2MgY29udHJvbCBpcyByZWFkeS4gKi8KI2lmZGVmIEdUX1JNR01UX0FDQ0VTUwogICAgewogICAgICBIV19ERVZfUkVHX0FDQ0VTUyByZWdBY2Nlc3M7CgogICAgICByZWdBY2Nlc3MuZW50cmllcyA9IDE7CiAgCiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5jbWQgPSBIV19SRUdfV0FJVF9USUxMXzA7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5hZGRyID0gQ0FMQ19TTUlfREVWX0FERFIoZGV2LCAwLCBHTE9CQUwyX1JFR19BQ0NFU1MpOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0ucmVnID0gUURfUkVHX1NDUkFUQ0hfTUlTQzsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmRhdGEgPSAxNTsKICAgICAgcmV0VmFsID0gaHdBY2Nlc3NNdWx0aVJlZ3MoZGV2LCAmcmVnQWNjZXNzKTsKICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICB7CiAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnZ0dVJlZ3NTZW0pOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgIH0KICAgIH0KI2Vsc2UKICAgICAgIHRtcERhdGEgPSAxOwogICAgd2hpbGUodG1wRGF0YSA9PSAxKQogICAgICAgewogICAgICAgIHJldFZhbCA9IGh3R2V0R2xvYmFsMlJlZ0ZpZWxkKGRldixRRF9SRUdfU0NSQVRDSF9NSVNDLDE1LDEsJnRtcERhdGEpOwogICAgICAgICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgICAgICB7CiAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICAgICB9CiAgICB9CiNlbmRpZgoKICAgIHRtcERhdGEgPSAgKEdUX1UxNikoKDEgPDwgMTUpIHwgKHBvaW50IDw8IDgpIHwgZGF0YSk7CgogICAgcmV0VmFsID0gaHdXcml0ZUdsb2JhbDJSZWcoZGV2LCBRRF9SRUdfU0NSQVRDSF9NSVNDLCB0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICBndFNlbUdpdmUoZGV2LGRldi0+dGJsUmVnc1NlbSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCgoKICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKCiAgICAgICByZXR1cm4gcmV0VmFsOwoKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgU2NyYXRjaCBhbmQgTWlzYyBjb250cm9sIGRhdGEgZnJvbSB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyLiAKKiAgICAgICAgVGhlIHJlZ2lzdGVyIG9mIFNjcmF0Y2ggYW5kIE1pc2MgY29udHJvbCBhcmUuCiogICAgICAgICAgICAgICAgU2NyYXRjaCBCeXRlIDAKKiAgICAgICAgICAgICAgICBTY3JhdGNoIEJ5dGUgMQoqICAgICAgICAgICAgICAgIEdQSU8gQ29uZmlndXJhdGlvbgoqICAgICAgICAgICAgICAgIFJlc2VydmVkIGZvciBmdXR1cmUgdXNlCiogICAgICAgICAgICAgICAgR1BJTyBEaXJlY3Rpb24KKiAgICAgICAgICAgICAgICBHUElPIERhdGEKKiAgICAgICAgICAgICAgICBDT05GSUcgRGF0YSAwCiogICAgICAgICAgICAgICAgQ09ORklHIERhdGEgMQoqICAgICAgICAgICAgICAgIENPTkZJRyBEYXRhIDIKKiAgICAgICAgICAgICAgICBDT05GSUcgRGF0YSAzCiogICAgICAgICAgICAgICAgU3luY0UgJiBUQUlDTEsxMjWScyBEcml2ZQoqICAgICAgICAgICAgICAgIFA1knMgJiBDTEsxMjWScyBDbG9jayBEcml2ZQoqICAgICAgICAgICAgICAgIFA2knMgQ2xvY2sgRHJpdmUKKiAgICAgICAgICAgICAgICBFRVBST00gUGFkIGRyaXZlCgoqCiogSU5QVVRTOgoqICAgICAgICBwb2ludCAtIFBvaW50ZXIgdG8gdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgcmVnaXN0ZXIuCioKKiBPVVRQVVRTOgoqICAgICAgICBkYXRhIC0gU2NyYXRjaCBhbmQgTWlzYy4gQ29udHJvbCBkYXRhIHJlYWQgZnJvbSB0aGUgcmVnaXN0ZXIgCiogICAgICAgICAgICAgICAgcG9pbnRlZCB0byBieSB0aGUgcG9pbnQgYWJvdmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX1UzMiAgICAgICAgICAgIHBvaW50LAogICAgT1VUICBHVF9VOCAgICAgICAgICAgICpkYXRhCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBPVVQgIEdUX1UxNiAgICAgICAgICAgIHRtcERhdGE7CgogICAgaWYgKHBvaW50ID4gR1RfU0NSQVRfTUlTQ19SRUdfTUFYKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfQkFEX1BBUkFNXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgIH0KCiAgICBpZiAocG9pbnQ+MHg3ZikKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgZ3RTZW1UYWtlKGRldixkZXYtPnRibFJlZ3NTZW0sT1NfV0FJVF9GT1JFVkVSKTsKCiAgICAvKiBwcm9ncmFtIFFvUyBXZWlnaHQgVGFibGUsIDQgc2VxdWVuY2VzIGF0IGEgdGltZSAqLwoKI2lmZGVmIEdUX1JNR01UX0FDQ0VTUwogICAgewogICAgICBIV19ERVZfUkVHX0FDQ0VTUyByZWdBY2Nlc3M7CgogICAgICByZWdBY2Nlc3MuZW50cmllcyA9IDI7CiAgCiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5jbWQgPSBIV19SRUdfV0FJVF9USUxMXzA7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFswXS5hZGRyID0gQ0FMQ19TTUlfREVWX0FERFIoZGV2LCAwLCBHTE9CQUwyX1JFR19BQ0NFU1MpOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMF0ucmVnID0gUURfUkVHX1NDUkFUQ0hfTUlTQzsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzBdLmRhdGEgPSAxNTsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzFdLmNtZCA9IEhXX1JFR19SRUFEOwogICAgICByZWdBY2Nlc3MucndfcmVnX2xpc3RbMV0uYWRkciA9IENBTENfU01JX0RFVl9BRERSKGRldiwgMCwgR0xPQkFMMl9SRUdfQUNDRVNTKTsKICAgICAgcmVnQWNjZXNzLnJ3X3JlZ19saXN0WzFdLnJlZyA9IFFEX1JFR19TQ1JBVENIX01JU0M7CiAgICAgIHJlZ0FjY2Vzcy5yd19yZWdfbGlzdFsxXS5kYXRhID0gMDsKICAgICAgcmV0VmFsID0gaHdBY2Nlc3NNdWx0aVJlZ3MoZGV2LCAmcmVnQWNjZXNzKTsKICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICB7CiAgICAgICAgZ3RTZW1HaXZlKGRldixkZXYtPnZ0dVJlZ3NTZW0pOwogICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgfQogICAgIHRtcERhdGEgPSBxZExvbmcyU2hvcnQocmVnQWNjZXNzLnJ3X3JlZ19saXN0WzFdLmRhdGEpOwogICAgfQojZWxzZQogICAgZG8gewogICAgICAgIHJldFZhbCA9IGh3UmVhZEdsb2JhbDJSZWcoZGV2LCBRRF9SRUdfU0NSQVRDSF9NSVNDLCAmdG1wRGF0YSk7CiAgICAgICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgICAgIHsKICAgICAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKICAgICAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgICAgICB9CiAgICB9IHdoaWxlICh0bXBEYXRhJjB4ODAwMCk7CiNlbmRpZgoKICAgICpkYXRhID0gdG1wRGF0YSYweGZmOwoKICAgIGd0U2VtR2l2ZShkZXYsZGV2LT50YmxSZWdzU2VtKTsKCgogICAgcmV0dXJuIHJldFZhbDsKfQoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0U2NyYXRjaEJpdHMKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBTZXQgYml0cyB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxzY3JhdGNoIGJ5dGUgMCBhbmQgMT4uCiogICAgICAgIFRoZXNlIGJpdHMgYXJlIDEwMCUgYXZhaWxhYmxlIHRvIHNvZnR3YXJlIGZvciB3aGF0ZXZlciBwdXJwb3NlIGRlc2lyZWQuIAoqICAgICAgICBUaGVzZSBiaXRzIGRvIG5vdCBjb25uZWN0IHRvIGFueSBoYXJkd2FyZSBmdW5jdGlvbi4KKgoqIElOUFVUUzoKKiAgICAgICAgc2NyaXRjaCAtIHdyaXR0ZW4gYml0cy4KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0U2NyYXRjaEJpdHMKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTE2ICAgICAgICAgICAgc2NyYXRjaAopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3N5c1NldFNjcmF0Y2hCaXRzIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c1NldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1NDUkFUXzAsIChHVF9VOCkoc2NyYXRjaCYweGZmKSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICByZXRWYWwgPSBnc3lzU2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfU0NSQVRfMSwgKEdUX1U4KSgoc2NyYXRjaD4+OCkmMHhmZikpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0U2NyYXRjaEJpdHMKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgYml0cyBmcm9tIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPHNjcmF0Y2ggYnl0ZSAwIGFuZCAxPi4KKiAgICAgICAgVGhlc2UgYml0cyBhcmUgMTAwJSBhdmFpbGFibGUgdG8gc29mdHdhcmUgZm9yIHdoYXRldmVyIHB1cnBvc2UgZGVzaXJlZC4gCiogICAgICAgIFRoZXNlIGJpdHMgZG8gbm90IGNvbm5lY3QgdG8gYW55IGhhcmR3YXJlIGZ1bmN0aW9uLgoqCiogSU5QVVRTOgoqICAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICAgc2NyaXRjaCAtIHJlYWQgYml0cy4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRTY3JhdGNoQml0cwooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIE9VVCAgR1RfVTE2ICAgICAgICAgICAgKnNjcmF0Y2gKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldFNjcmF0Y2hCaXRzIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1NDUkFUXzEsICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQogICAgKnNjcmF0Y2ggPSBkYXRhOwogICAgKnNjcmF0Y2ggPSAqc2NyYXRjaDw8ODsKICAgIHJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19TQ1JBVF8wLCAmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KICAgIAogICAgKnNjcmF0Y2ggfD0gZGF0YTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0R3Bpb0NvbmZpZ01vZAoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFNldCBiaXRzIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPEdQSU8gQ29uZmlndXJhdGlvbj4KKiAgICAgICAgdG8gY29uZmlndXJlIEdQSU8gbW9kZS4KKiAgICAgICAgVGhlIGJpdHMgYXJlIHNoYXJlZCBHZW5lcmFsIFB1cnBvc2UgSW5wdXQgT3V0cHV0IG1vZGUgQml0czoKKiAgICAgICAgQml0IDYgLSBHVF9HUElPX0JJVF82OiAgICAxOkdQSU9bNl0gICAgMDpTRV9SQ0xLMQoqICAgICAgICBCaXQgNSAtIEdUX0dQSU9fQklUXzU6ICAgIDE6R1BJT1s1XSAgICAwOlNFX1JDTEswCiogICAgICAgIE5vdywgZm9sbG9pbmcgYml0cyBhcmUgcmVhZCBvbmx5LiAKKiAgICAgICAgQml0IDQgLSBHVF9HUElPX0JJVF80OiAgICAxOkdQSU9bNF0gICAgMDoKKiAgICAgICAgQml0IDMgLSBHVF9HUElPX0JJVF8zOiAgICAxOkdQSU9bM10gICAgMDoKKiAgICAgICAgQml0IDIgLSBHVF9HUElPX0JJVF8yOiAgICAxOkdQSU9bMl0gICAgMDoKKiAgICAgICAgQml0IDEgLSBHVF9HUElPX0JJVF8xOiAgICAxOkdQSU9bMV0gICAgMDpQNl9DT0wKKiAgICAgICAgQml0IDAgLSBHVF9HUElPX0JJVF8wOiAgICAxOkdQSU9bMF0gICAgMDpQNl9DUlMKKgoqIElOUFVUUzoKKiAgICAgICAgbW9kZSAtIE9SIFtHVF9HUElPX0JJVF94XQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRHcGlvQ29uZmlnTW9kCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgSU4gIEdUX1UzMiAgICAgICAgICAgIG1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KCiAgICBEQkdfSU5GTygoImdzeXNTZXRHcGlvQ29uZmlnTW9kIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c1NldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0dQSU9fQ0ZHLCAoR1RfVTgpKG1vZGUmMHg3ZikpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoKICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRHcGlvQ29uZmlnTW9kCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgR2V0IG1vZGUgZnJvbSB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxHUElPIENvbmZpZ3VyYXRpb24+LgoqICAgICAgICBUaGUgYml0cyBhcmUgc2hhcmVkIEdlbmVyYWwgUHVycG9zZSBJbnB1dCBPdXRwdXQgbW9kZSBCaXRzOgoqICAgICAgICBCaXQgNiAtIEdUX0dQSU9fQklUXzY6ICAgIDE6R1BJT1s2XSAgICAwOlNFX1JDTEsxCiogICAgICAgIEJpdCA1IC0gR1RfR1BJT19CSVRfNTogICAgMTpHUElPWzVdICAgIDA6U0VfUkNMSzAKKiAgICAgICAgTm93LCBmb2xsb2luZyBiaXRzIGFyZSByZWFkIG9ubHkuIAoqICAgICAgICBCaXQgNCAtIEdUX0dQSU9fQklUXzQ6ICAgIDE6R1BJT1s0XSAgICAwOgoqICAgICAgICBCaXQgMyAtIEdUX0dQSU9fQklUXzM6ICAgIDE6R1BJT1szXSAgICAwOgoqICAgICAgICBCaXQgMiAtIEdUX0dQSU9fQklUXzI6ICAgIDE6R1BJT1syXSAgICAwOgoqICAgICAgICBCaXQgMSAtIEdUX0dQSU9fQklUXzE6ICAgIDE6R1BJT1sxXSAgICAwOlA2X0NPTAoqICAgICAgICBCaXQgMCAtIEdUX0dQSU9fQklUXzA6ICAgIDE6R1BJT1swXSAgICAwOlA2X0NSUwoqCiogSU5QVVRTOgoqICAgICAgICBOb25lLgoqCiogT1VUUFVUUzoKKiAgICAgICAgbW9kZSAtIE9SIFtHVF9HUElPX0JJVF94XQoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldEdwaW9Db25maWdNb2QKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgKm1vZGUKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldEdwaW9Db25maWdNb2QgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICByZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfR1BJT19DRkcsICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQogICAgCiAgICAqbW9kZSA9IDB4N2YmZGF0YTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0R3Bpb0RpcmVjdGlvbgoqCiogREVTQ1JJUFRJT046CiogICAgICAgIFNldCBHcGlvIGRpcmVjdGlvbiB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxHUElPIERpcmVjdGlvbj4uCiogICAgICAgIFRoZSBiaXRzIGFyZSB1c2VkIHRvIGNvbnRyb2wgdGhlIGRpcmVjdGlvbiBvZiBHUElPWzY6MF0uIAoqICAgICAgICBXaGVuIGEgR1BJT5JzIGJpdCBpcyBzZXQgdG8gYSBvbmUgdGhhdCBHUElPIHdpbGwgYmVjb21lIGFuIGlucHV0LiBXaGVuIGEKKiAgICAgICAgR1BJT5JzIGJpdCBpcyBjbGVhcmVkIHRvIGEgemVybyB0aGF0IEdQSU8gd2lsbCBiZWNvbWUgYW4gb3V0cHV0CiogICAgICAgIEdlbmVyYWwgUHVycG9zZSBJbnB1dCBPdXRwdXQgZGlyZWN0aW9uIGJpdHMgYXJlOgoqICAgICAgICBCaXQgNiAtIEdUX0dQSU9fQklUXzYKKiAgICAgICAgQml0IDUgLSBHVF9HUElPX0JJVF81CiogICAgICAgIEJpdCA0IC0gR1RfR1BJT19CSVRfNAoqICAgICAgICBCaXQgMyAtIEdUX0dQSU9fQklUXzMKKiAgICAgICAgQml0IDIgLSBHVF9HUElPX0JJVF8yCiogICAgICAgIEJpdCAxIC0gR1RfR1BJT19CSVRfMQoqICAgICAgICBCaXQgMCAtIEdUX0dQSU9fQklUXzAKKgoqIElOUFVUUzoKKiAgICAgICAgZGlyIC0gT1IgW0dUX0dQSU9fQklUX3hdCioKKiBPVVRQVVRTOgoqICAgICAgICBOb25lLgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c1NldEdwaW9EaXJlY3Rpb24KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgZGlyCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCgogICAgREJHX0lORk8oKCJnc3lzU2V0R3Bpb0RpcmVjdGlvbiBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIHJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19HUElPX0RJUiwgKEdUX1U4KShkaXImMHg3ZikpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoKICAgIHJldHVybiBHVF9PSzsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNHZXRHcGlvRGlyZWN0aW9uCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgZ2V0IEdwaW8gZGlyZWN0aW9uIGZyb20gdGhlIFNjcmF0Y2ggYW5kIE1pc2MgQ29udHJvbCByZWdpc3RlciA8R1BJTyBEaXJlY3Rpb24+LgoqICAgICAgICBUaGUgYml0cyBhcmUgdXNlZCB0byBjb250cm9sIHRoZSBkaXJlY3Rpb24gb2YgR1BJT1s2OjBdLiAKKiAgICAgICAgV2hlbiBhIEdQSU+ScyBiaXQgaXMgc2V0IHRvIGEgb25lIHRoYXQgR1BJTyB3aWxsIGJlY29tZSBhbiBpbnB1dC4gV2hlbiBhCiogICAgICAgIEdQSU+ScyBiaXQgaXMgY2xlYXJlZCB0byBhIHplcm8gdGhhdCBHUElPIHdpbGwgYmVjb21lIGFuIG91dHB1dAoqICAgICAgICBHZW5lcmFsIFB1cnBvc2UgSW5wdXQgT3V0cHV0IGRpcmVjdGlvbiBiaXRzIGFyZToKKiAgICAgICAgQml0IDYgLSBHVF9HUElPX0JJVF82CiogICAgICAgIEJpdCA1IC0gR1RfR1BJT19CSVRfNQoqICAgICAgICBCaXQgNCAtIEdUX0dQSU9fQklUXzQKKiAgICAgICAgQml0IDMgLSBHVF9HUElPX0JJVF8zCiogICAgICAgIEJpdCAyIC0gR1RfR1BJT19CSVRfMgoqICAgICAgICBCaXQgMSAtIEdUX0dQSU9fQklUXzEKKiAgICAgICAgQml0IDAgLSBHVF9HUElPX0JJVF8wCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICBkaXIgLSBPUiBbR1RfR1BJT19CSVRfeF0KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRHcGlvRGlyZWN0aW9uCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgT1VUICBHVF9VMzIgICAgICAgICAgICAqZGlyCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRHcGlvRGlyZWN0aW9uIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0dQSU9fRElSLCAmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICAqZGlyID0gZGF0YTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1NldEdwaW9EYXRhCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgU2V0IEdwaW8gZGF0YSB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxHUElPIGRhdGE+LgoqICAgICAgICBXaGVuIGEgR1BJT5JzIGJpdCBpcyBzZXQgdG8gYmUgYW4gaW5wdXQsIGRhdGEgd3JpdHRlbiB0byB0aGlzIGJpdCB3aWxsIGdvIAoqICAgICAgICB0byBhIGhvbGRpbmcgcmVnaXN0ZXIgYnV0IHdpbGwgbm90IGFwcGVhciBvbiB0aGUgcGluIG5vciBpbiB0aGlzIHJlZ2lzdGVyLiAKKiAgICAgICAgUmVhZHMgb2YgdGhpcyByZWdpc3RlciB3aWxsIHJldHVybiB0aGUgYWN0dWFsLCByZWFsLXRpbWUsIGRhdGEgdGhhdCBpcyAKKiAgICAgICAgYXBwZWFyaW5nIG9uIHRoZSBHUElPknMgcGluLgoqICAgICAgICBXaGVuIGEgR1BJT5JzIGJpdCBpcyBzZXQgdG8gYmUgYW4gb3V0cHV0LCBkYXRhIHdyaXR0ZW4gdG8gdGhpcyBiaXQgd2lsbCBnbyAKKiAgICAgICAgdG8gYSBob2xkaW5nIHJlZ2lzdGVyIGFuZCB3aWxsIGFwcGVhciBvbiB0aGUgR1BJT5JzIHBpbi4gUmVhZHMgb2YgdGhpcyByZWdpc3RlciAKKiAgICAgICAgd2lsbCByZXR1cm4gdGhlIGFjdHVhbCwgcmVhbC10aW1lLCBkYXRhIHRoYXQgaXMgYXBwZWFyaW5nIG9uIHRoZSBHUElPknMgcGluIAoqICAgICAgICAod2hpY2ggaW4gdGhpcyBjYXNlIHNob3VsZCBiZSB0aGUgZGF0YSB3cml0dGVuLCBidXQgaWYgaXRzIGlzbpJ0IHRoYXQgd291bGQgCiogICAgICAgIGJlIGFuIGluZGljYXRpb24gb2YgYSBjb25mbGljdCkuCiogICAgICAgIFdoZW4gYSBwaW6ScyBkaXJlY3Rpb24gY2hhbmdlcyBmcm9tIGlucHV0IHRvIG91dHB1dCwgdGhlIGRhdGEgbGFzdCB3cml0dGVuIAoqICAgICAgICB0byB0aGUgaG9sZGluZyByZWdpc3RlciBhcHBlYXJzIG9uIHRoZSBHUElPknMgcGluCiogICAgICAgIEdlbmVyYWwgUHVycG9zZSBJbnB1dCBPdXRwdXQgZGF0YSBiaXRzIGFyZToKKiAgICAgICAgQml0IDYgLSBHVF9HUElPX0JJVF82CiogICAgICAgIEJpdCA1IC0gR1RfR1BJT19CSVRfNQoqICAgICAgICBCaXQgNCAtIEdUX0dQSU9fQklUXzQKKiAgICAgICAgQml0IDMgLSBHVF9HUElPX0JJVF8zCiogICAgICAgIEJpdCAyIC0gR1RfR1BJT19CSVRfMgoqICAgICAgICBCaXQgMSAtIEdUX0dQSU9fQklUXzEKKiAgICAgICAgQml0IDAgLSBHVF9HUElPX0JJVF8wCioKKiBJTlBVVFM6CiogICAgICAgIGRhdGEgLSBPUiBbR1RfR1BJT19CSVRfeF0KKgoqIE9VVFBVVFM6CiogICAgICAgIE5vbmUuCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzU2V0R3Bpb0RhdGEKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgZGF0YQopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwoKICAgIERCR19JTkZPKCgiZ3N5c1NldEdwaW9EYXRhIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c1NldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0dQSU9fREFULCAoR1RfVTgpKGRhdGEmMHg3ZikpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgoKICAgIHJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldEdwaW9EYXRhCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgZ2V0IEdwaW8gZGF0YSB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxHUElPIGRhdGE+LgoqICAgICAgICBXaGVuIGEgR1BJT5JzIGJpdCBpcyBzZXQgdG8gYmUgYW4gaW5wdXQsIGRhdGEgd3JpdHRlbiB0byB0aGlzIGJpdCB3aWxsIGdvIAoqICAgICAgICB0byBhIGhvbGRpbmcgcmVnaXN0ZXIgYnV0IHdpbGwgbm90IGFwcGVhciBvbiB0aGUgcGluIG5vciBpbiB0aGlzIHJlZ2lzdGVyLiAKKiAgICAgICAgUmVhZHMgb2YgdGhpcyByZWdpc3RlciB3aWxsIHJldHVybiB0aGUgYWN0dWFsLCByZWFsLXRpbWUsIGRhdGEgdGhhdCBpcyAKKiAgICAgICAgYXBwZWFyaW5nIG9uIHRoZSBHUElPknMgcGluLgoqICAgICAgICBXaGVuIGEgR1BJT5JzIGJpdCBpcyBzZXQgdG8gYmUgYW4gb3V0cHV0LCBkYXRhIHdyaXR0ZW4gdG8gdGhpcyBiaXQgd2lsbCBnbyAKKiAgICAgICAgdG8gYSBob2xkaW5nIHJlZ2lzdGVyIGFuZCB3aWxsIGFwcGVhciBvbiB0aGUgR1BJT5JzIHBpbi4gUmVhZHMgb2YgdGhpcyByZWdpc3RlciAKKiAgICAgICAgd2lsbCByZXR1cm4gdGhlIGFjdHVhbCwgcmVhbC10aW1lLCBkYXRhIHRoYXQgaXMgYXBwZWFyaW5nIG9uIHRoZSBHUElPknMgcGluIAoqICAgICAgICAod2hpY2ggaW4gdGhpcyBjYXNlIHNob3VsZCBiZSB0aGUgZGF0YSB3cml0dGVuLCBidXQgaWYgaXRzIGlzbpJ0IHRoYXQgd291bGQgCiogICAgICAgIGJlIGFuIGluZGljYXRpb24gb2YgYSBjb25mbGljdCkuCiogICAgICAgIFdoZW4gYSBwaW6ScyBkaXJlY3Rpb24gY2hhbmdlcyBmcm9tIGlucHV0IHRvIG91dHB1dCwgdGhlIGRhdGEgbGFzdCB3cml0dGVuIAoqICAgICAgICB0byB0aGUgaG9sZGluZyByZWdpc3RlciBhcHBlYXJzIG9uIHRoZSBHUElPknMgcGluCiogICAgICAgIEdlbmVyYWwgUHVycG9zZSBJbnB1dCBPdXRwdXQgZGF0YSBiaXRzIGFyZToKKiAgICAgICAgQml0IDYgLSBHVF9HUElPX0JJVF82CiogICAgICAgIEJpdCA1IC0gR1RfR1BJT19CSVRfNQoqICAgICAgICBCaXQgNCAtIEdUX0dQSU9fQklUXzQKKiAgICAgICAgQml0IDMgLSBHVF9HUElPX0JJVF8zCiogICAgICAgIEJpdCAyIC0gR1RfR1BJT19CSVRfMgoqICAgICAgICBCaXQgMSAtIEdUX0dQSU9fQklUXzEKKiAgICAgICAgQml0IDAgLSBHVF9HUElPX0JJVF8wCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICBkYXRhIC0gT1IgW0dUX0dQSU9fQklUX3hdCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzR2V0R3Bpb0RhdGEKKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTMyICAgICAgICAgICAgKmRhdGEKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICB0bXBEYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldEdwaW9EYXRhIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0dQSU9fREFULCAmdG1wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICAqZGF0YSA9IHRtcERhdGE7CgogICAgcmV0dXJuIEdUX09LOwoKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldENvbmZpZ0RhdGEKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgICBHZXQgUmVzZXQgQ29uZmlndXJhdGlvbiBQaW4gRGF0YSAwLTMuIAoqICAgICAgICBUaGVzZSByZWdpc3RlcnMgcmV0dXJuIHRoZSB2YWx1ZXMgb2JzZXJ2ZWQgYWZ0ZXIgYSBoYXJkd2FyZSBSZXNldCBvbiB0aGUgCiogICAgICAgIGxpc3RlZCBDT05GSUcgZGF0YSBsaXN0ZWQgYmVsb3cuCiogICAgICAgICAgICBDb25maWcgZGF0YSAwOgoqICAgICAgICAgICAgICBCaXQgICAgQ29uZmlnICAgIFBpbidzIFByaW1hcnkgTmFtZQoqICAgICAgICAgICAgICAgIDAgICAgVVNFUlswXSAgICAgICAgUDZfT1VURFs1XQoqICAgICAgICAgICAgICAgIDEgICAgVVNFUlsxXSAgICAgICAgUDZfT1VURFs2XQoqICAgICAgICAgICAgICAgIDIgICAgVVNFUlsyXSAgICAgICAgUDZfT1VURFs3XQoqICAgICAgICAgICAgICAgIDMgICAgQUREUlswXSAgICAgICAgUDVfT1VURFswXQoqICAgICAgICAgICAgICAgIDQgICAgQUREUlsxXSAgICAgICAgUDVfT1VURFs1XQoqICAgICAgICAgICAgICAgIDUgICAgQUREUlsyXSAgICAgICAgUDVfT1VURFs2XQoqICAgICAgICAgICAgICAgIDYgICAgQUREUl0zXSAgICAgICAgUDVfT1VURFs3XQoqICAgICAgICAgICAgICAgIDcgICAgQUREUls0XSAgICAgICAgUDVfT1VURFsxXQoqICAgICAgICAgICAgQ29uZmlnIGRhdGEgMToKKiAgICAgICAgICAgICAgICAwICAgIExFRF9TRUxbMF0gICAgUDFfTEVECiogICAgICAgICAgICAgICAgMSAgICBMRURfU0VMWzFdICAgIFAyX0xFRAoqICAgICAgICAgICAgICAgIDIgICAgNENPTCBQM19MRUQKKiAgICAgICAgICAgICAgICAzICAgIE5vcm1DeCAgICAgICAgUDRfTEVECiogICAgICAgICAgICAgICAgNCAgICBKdW1ibyAgICAgICAgUDBfTEVECiogICAgICAgICAgICAgICAgNSAgICBFRV9XRSAgICAgICAgRUVfQ1MvQzJfTEVECiogICAgICAgICAgICAgICAgNiAgICBGRF9GTE9XICAgICAgICBFRV9DTEsvQzFfTEVECiogICAgICAgICAgICAgICAgNyAgICBIRF9GTE9XICAgICAgICBFRV9ESU4vQzBfTEVECiogICAgICAgICAgICBDb25maWcgZGF0YSAyOgoqICAgICAgICAgICAgICAgIDAgICAgUDVfTU9ERVswXSAgICBQNV9PVVREWzJdCiogICAgICAgICAgICAgICAgMSAgICBQNV9NT0RFWzFdICAgIFA1X09VVERbM10KKiAgICAgICAgICAgICAgICAyICAgIFA1X01PREVbMl0gICAgUDVfT1VURFs0XQoqICAgICAgICAgICAgICAgIDMgICAgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UKKiAgICAgICAgICAgICAgICA0ICAgIFA2X01PREVbMF0gICAgUDZfT1VURFsyXQoqICAgICAgICAgICAgICAgIDUgICAgUDZfTU9ERVsxXSAgICBQNl9PVVREWzNdCiogICAgICAgICAgICAgICAgNiAgICBQNl9NT0RFWzJdICAgIFA2X09VVERbNF0KKiAgICAgICAgICAgICAgICA3ICAgIFJlc2VydmVkIGZvciBmdXR1cmUgdXNlCiogICAgICAgICAgICBDb25maWcgZGF0YSAzOgoqICAgICAgICAgICAgICAgIDAgICAgUk1VX01PREVbMF0gUDZfT1VURFswXQoqICAgICAgICAgICAgICAgIDEgICAgUk1VX01PREVbMV0gUDZfT1VURFsxXQoqICAgICAgICAgICAgICAgIDIgICAgU19WRERPU1swXSAgICBQVFBfVFJJRyAKKiAgICAgICAgICAgICAgICAzICAgIENMSzEyNUVOICAgIENMSzEyNQoqICAgICAgICAgICAgICAgIDQgICAgUDVfVkRET1NbMF0gUDVfR1RYQ0xLCiogICAgICAgICAgICAgICAgNSAgICBQNV9WRERPU1sxXSBQNV9PVVRFTgoqICAgICAgICAgICAgICAgIDYgICAgUDZfVkRET1NbMF0gUDVfR1RYQ0xLCiogICAgICAgICAgICAgICAgNyAgICBQNl9WRERPU1sxXSBQNl9PVVRFTgoqIElOUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIE9VVFBVVFM6CiogICAgICAgY2ZnRGF0IC0gR1RfQ09ORklHX0RUVEEKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRDb25maWdEYXRhCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAgICAgKmRldiwKICAgIE9VVCAgR1RfQ09ORklHX0RBVEEgICAgICAgICpjZmdEYXRhCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgdG1wRGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRDb25maWdEYXRhIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0NGR19EQVQwLCAmdG1wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICBjZmdEYXRhLT5jZmdEYXRhMC5CeXRlID0gdG1wRGF0YTsKCiAgICByZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfQ0ZHX0RBVDEsICZ0bXBEYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIGNmZ0RhdGEtPmNmZ0RhdGExLkJ5dGUgPSB0bXBEYXRhOwoKICAgIHJldFZhbCA9IGdzeXNHZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19DRkdfREFUMiwgJnRtcERhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgY2ZnRGF0YS0+Y2ZnRGF0YTIuQnl0ZSA9IHRtcERhdGE7CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX0NGR19EQVQzLCAmdG1wRGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICBjZmdEYXRhLT5jZmdEYXRhMy5CeXRlID0gdG1wRGF0YTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1NldFN5bmNFVGFpCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgU2V0IFN5bmNFIGFuZCBUYWkgdG8gdGhlIFNjcmF0Y2ggYW5kIE1pc2MuIENvbnRyb2wgcmVnaXN0ZXIgPFN5bmNFIGFuZCBUQUkgcGFkPi4KKgoqIElOUFVUUzoKKiAgICAgICAgenByIC0gWlBSIGZvciBTeW5jRSBhbmQgVEFJCiogICAgICAgIHpuciAtIFpOUiBmb3IgU3luY0UgYW5kIFRBSQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRTeW5jRVRhaQooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpwciwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpucgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0U3luY0VUYWkgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBpZiAoKHpwcj4weDcpIHx8ICh6bnI+MHg3KSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgZGF0YSA9ICgoenByJjB4Nyk8PDMpIHwgKHpuciYweDcpOwoKICAgIHJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19TWU5DRSwgZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldFN5bmNFVGFpCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgR2V0IFN5bmNFIGFuZCBUYWkgZnJvbSB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxTeW5jRSBhbmQgVEFJIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICB6cHIgLSBaUFIgZm9yIFN5bmNFIGFuZCBUQUkKKiAgICAgICAgem5yIC0gWk5SIGZvciBTeW5jRSBhbmQgVEFJKgoqCiogUkVUVVJOUzoKKiAgICAgICAgR1RfT0sgICAgICAtIG9uIHN1Y2Nlc3MKKiAgICAgICAgR1RfRkFJTCAgICAtIG9uIGVycm9yCiogICAgICAgIEdUX0JBRF9QQVJBTSAtIGlmIGlucHV0IHBhcmFtZXRlcnMgYXJlIGJleW9uZCByYW5nZS4KKiAgICAgICAgR1RfTk9UX1NVUFBPUlRFRCAtIGlmIGN1cnJlbnQgZGV2aWNlIGRvZXMgbm90IHN1cHBvcnQgdGhpcyBmZWF0dXJlLgoqCiogQ09NTUVOVFM6CiogICAgICAgIE5vbmUKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpHVF9TVEFUVVMgZ3N5c0dldFN5bmNFVGFpCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgT1VUICBHVF9VOCAgICAgICAgICAgICp6cHIsCiAgICBPVVQgIEdUX1U4ICAgICAgICAgICAgKnpucgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzR2V0U3luY0VUYWkgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICByZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfU1lOQ0UsICZkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQogICAgCiAgICAqenByID0gMHg3ICYoZGF0YT4+Myk7CiAgICAqem5yID0gMHg3ICYoZGF0YSk7CgogICAgcmV0dXJuIEdUX09LOwoKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c1NldFA2X0Nsb2NrCioKKiBERVNDUklQVElPTjoKKiAgICAgICAgU2V0IFA2X2Nsb2NrIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPFA2X0Nsb2NrIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgIHpwciAtIFpQUiBmb3IgUDZfQ2xvY2sKKiAgICAgICAgem5yIC0gWk5SIGZvciBQNl9DbG9jawoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRQNl9DbG9jawooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpwciwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpucgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0UDZfQ2xvY2sgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBpZiAoKHpwcj4weDcpIHx8ICh6bnI+MHg3KSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgZGF0YSA9ICgoenByJjB4Nyk8PDMpIHwgKHpuciYweDcpOwoKICAgIHJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19QNl9DTEssIGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0UDZfQ2xvY2sKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIEdldCBQNl9jbG9jayBmcm9tIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPFA2X0Nsb2NrIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICB6cHIgLSBaUFIgZm9yIFA2X0Nsb2NrCiogICAgICAgIHpuciAtIFpOUiBmb3IgUDZfQ2xvY2sKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRQNl9DbG9jawooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqenByLAogICAgT1VUICBHVF9VOCAgICAgICAgICAgICp6bnIKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldFA2X0Nsb2NrIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1A2X0NMSywgJmRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CiAgICAKICAgICp6cHIgPSAweDcgJihkYXRhPj4zKTsKICAgICp6bnIgPSAweDcgJihkYXRhKTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIGdzeXNTZXRQNV9DbG9jawoqCiogREVTQ1JJUFRJT046CiogICAgICAgU2V0IFA1X2Nsb2NrIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPFA1X0Nsb2NrIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgIHpwciAtIFpQUiBmb3IgUDVfQ2xvY2sKKiAgICAgICAgem5yIC0gWk5SIGZvciBQNV9DbG9jawoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRQNV9DbG9jawooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpwciwKICAgIElOICBHVF9VOCAgICAgICAgICAgIHpucgopCnsKICAgIEdUX1NUQVRVUyAgICByZXRWYWw7ICAgICAgICAgLyogRnVuY3Rpb25zIHJldHVybiB2YWx1ZS4gICAgICAqLwogICAgR1RfVTggICAgICAgIGRhdGE7CgogICAgREJHX0lORk8oKCJnc3lzU2V0UDVfQ2xvY2sgQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICBpZiAoKHpwcj4weDcpIHx8ICh6bnI+MHg3KSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX0JBRF9QQVJBTVxuIikpOwogICAgICAgIHJldHVybiBHVF9CQURfUEFSQU07CiAgICB9CgogICAgZGF0YSA9ICgoenByJjB4Nyk8PDMpIHwgKHpuciYweDcpOwoKICAgIHJldFZhbCA9IGdzeXNTZXRTY3JhdGNoTWlzY0N0cmwoZGV2LCBHVF9TQ1JBVF9NSVNDX1JFR19QNV9DTEssIGRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CgogICAgcmV0dXJuIEdUX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzR2V0UDVfQ2xvY2sKKgoqIERFU0NSSVBUSU9OOgoqICAgICAgIEdldCBQNV9jbG9jayBmcm9tIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPFA1X0Nsb2NrIHBhZD4uCioKKiBJTlBVVFM6CiogICAgICAgIE5vbmUuCioKKiBPVVRQVVRTOgoqICAgICAgICB6cHIgLSBaUFIgZm9yIFA1X0Nsb2NrCiogICAgICAgIHpuciAtIFpOUiBmb3IgUDVfQ2xvY2sKKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNHZXRQNV9DbG9jawooCiAgICBJTiAgR1RfUURfREVWICAgICAgICAgKmRldiwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqenByLAogICAgT1VUICBHVF9VOCAgICAgICAgICAgICp6bnIKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c0dldFA2X0Nsb2NrIENhbGxlZC5cbiIpKTsKCiAgICAvKiBDaGVjayBpZiBTd2l0Y2ggc3VwcG9ydHMgdGhpcyBmZWF0dXJlLiAqLwogICAgaWYgKCFJU19JTl9ERVZfR1JPVVAoZGV2LERFVl9TQ1JBVENIX01JU0NfQ1RSTCkpCiAgICB7CiAgICAgICAgREJHX0lORk8oKCJHVF9OT1RfU1VQUE9SVEVEXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX05PVF9TVVBQT1JURUQ7CiAgICB9CgogICAgcmV0VmFsID0gZ3N5c0dldFNjcmF0Y2hNaXNjQ3RybChkZXYsIEdUX1NDUkFUX01JU0NfUkVHX1A1X0NMSywgJmRhdGEpOwogICAgaWYocmV0VmFsICE9IEdUX09LKQogICAgICAgewogICAgICAgICAgIERCR19JTkZPKCgiRmFpbGVkLlxuIikpOwogICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICB9CiAgICAKICAgICp6cHIgPSAweDcgJihkYXRhPj4zKTsKICAgICp6bnIgPSAweDcgJihkYXRhKTsKCiAgICByZXR1cm4gR1RfT0s7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBnc3lzU2V0RUVQUk9NCioKKiBERVNDUklQVElPTjoKKiAgICAgICBTZXQgRUVQUk9NIGN5Y2xlIHRvIHRoZSBTY3JhdGNoIGFuZCBNaXNjIENvbnRyb2wgcmVnaXN0ZXIgPEVFUFJPTSBwYWQ+LgoqCiogSU5QVVRTOgoqICAgICAgICBkc20gLSBEU00gZm9yIEVFUFJPTSBjeWNsZQoqICAgICAgICB6cHIgLSBaUFIgZm9yIEVFUFJPTSBjeWNsZQoqICAgICAgICB6bnIgLSBaTlIgZm9yIEVFUFJPTSBjeWNsZQoqCiogT1VUUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIFJFVFVSTlM6CiogICAgICAgIEdUX09LICAgICAgLSBvbiBzdWNjZXNzCiogICAgICAgIEdUX0ZBSUwgICAgLSBvbiBlcnJvcgoqICAgICAgICBHVF9CQURfUEFSQU0gLSBpZiBpbnB1dCBwYXJhbWV0ZXJzIGFyZSBiZXlvbmQgcmFuZ2UuCiogICAgICAgIEdUX05PVF9TVVBQT1JURUQgLSBpZiBjdXJyZW50IGRldmljZSBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgZmVhdHVyZS4KKgoqIENPTU1FTlRTOgoqICAgICAgICBOb25lCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KR1RfU1RBVFVTIGdzeXNTZXRFRVBST00KKAogICAgSU4gIEdUX1FEX0RFViAgICAgICAgICpkZXYsCiAgICBJTiAgR1RfVTggICAgICAgICAgICBkc20sCiAgICBJTiAgR1RfVTggICAgICAgICAgICB6cHIsCiAgICBJTiAgR1RfVTggICAgICAgICAgICB6bnIKKQp7CiAgICBHVF9TVEFUVVMgICAgcmV0VmFsOyAgICAgICAgIC8qIEZ1bmN0aW9ucyByZXR1cm4gdmFsdWUuICAgICAgKi8KICAgIEdUX1U4ICAgICAgICBkYXRhOwoKICAgIERCR19JTkZPKCgiZ3N5c1NldEVFUFJPTSBDYWxsZWQuXG4iKSk7CgogICAgLyogQ2hlY2sgaWYgU3dpdGNoIHN1cHBvcnRzIHRoaXMgZmVhdHVyZS4gKi8KICAgIGlmICghSVNfSU5fREVWX0dST1VQKGRldixERVZfU0NSQVRDSF9NSVNDX0NUUkwpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfTk9UX1NVUFBPUlRFRFxuIikpOwogICAgICAgIHJldHVybiBHVF9OT1RfU1VQUE9SVEVEOwogICAgfQoKICAgIGlmICgoenByPjB4NykgfHwgKHpucj4weDcpKQogICAgewogICAgICAgIERCR19JTkZPKCgiR1RfQkFEX1BBUkFNXG4iKSk7CiAgICAgICAgcmV0dXJuIEdUX0JBRF9QQVJBTTsKICAgIH0KCiAgICBkYXRhID0gKChkc20mMHgzKTw8NikgfCAoKHpwciYweDcpPDwzKSB8ICh6bnImMHg3KTsKCiAgICByZXRWYWwgPSBnc3lzU2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfRUVQUk9NLCBkYXRhKTsKICAgIGlmKHJldFZhbCAhPSBHVF9PSykKICAgICAgIHsKICAgICAgICAgICBEQkdfSU5GTygoIkZhaWxlZC5cbiIpKTsKICAgICAgICAgICByZXR1cm4gcmV0VmFsOwogICAgfQoKICAgIHJldHVybiBHVF9PSzsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogZ3N5c0dldEVFUFJPTQoqCiogREVTQ1JJUFRJT046CiogICAgICAgR2V0IEVFUFJPTSBjeWNsZSB0byB0aGUgU2NyYXRjaCBhbmQgTWlzYyBDb250cm9sIHJlZ2lzdGVyIDxFRVBST00gcGFkPi4KKgoqIElOUFVUUzoKKiAgICAgICAgTm9uZS4KKgoqIE9VVFBVVFM6CiogICAgICAgIGRzbSAtIERTTSBmb3IgRUVQUk9NIGN5Y2xlCiogICAgICAgIHpwciAtIFpQUiBmb3IgRUVQUk9NIGN5Y2xlCiogICAgICAgIHpuciAtIFpOUiBmb3IgRUVQUk9NIGN5Y2xlCioKKiBSRVRVUk5TOgoqICAgICAgICBHVF9PSyAgICAgIC0gb24gc3VjY2VzcwoqICAgICAgICBHVF9GQUlMICAgIC0gb24gZXJyb3IKKiAgICAgICAgR1RfQkFEX1BBUkFNIC0gaWYgaW5wdXQgcGFyYW1ldGVycyBhcmUgYmV5b25kIHJhbmdlLgoqICAgICAgICBHVF9OT1RfU1VQUE9SVEVEIC0gaWYgY3VycmVudCBkZXZpY2UgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCioKKiBDT01NRU5UUzoKKiAgICAgICAgTm9uZQoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkdUX1NUQVRVUyBnc3lzR2V0RUVQUk9NCigKICAgIElOICBHVF9RRF9ERVYgICAgICAgICAqZGV2LAogICAgT1VUICBHVF9VOCAgICAgICAgICAgICpkc20sCiAgICBPVVQgIEdUX1U4ICAgICAgICAgICAgKnpwciwKICAgIE9VVCAgR1RfVTggICAgICAgICAgICAqem5yCikKewogICAgR1RfU1RBVFVTICAgIHJldFZhbDsgICAgICAgICAvKiBGdW5jdGlvbnMgcmV0dXJuIHZhbHVlLiAgICAgICovCiAgICBHVF9VOCAgICAgICAgZGF0YTsKCiAgICBEQkdfSU5GTygoImdzeXNHZXRFRVBST00gQ2FsbGVkLlxuIikpOwoKICAgIC8qIENoZWNrIGlmIFN3aXRjaCBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuICovCiAgICBpZiAoIUlTX0lOX0RFVl9HUk9VUChkZXYsREVWX1NDUkFUQ0hfTUlTQ19DVFJMKSkKICAgIHsKICAgICAgICBEQkdfSU5GTygoIkdUX05PVF9TVVBQT1JURURcbiIpKTsKICAgICAgICByZXR1cm4gR1RfTk9UX1NVUFBPUlRFRDsKICAgIH0KCiAgICByZXRWYWwgPSBnc3lzR2V0U2NyYXRjaE1pc2NDdHJsKGRldiwgR1RfU0NSQVRfTUlTQ19SRUdfRUVQUk9NLCAmZGF0YSk7CiAgICBpZihyZXRWYWwgIT0gR1RfT0spCiAgICAgICB7CiAgICAgICAgICAgREJHX0lORk8oKCJGYWlsZWQuXG4iKSk7CiAgICAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KICAgIAogICAgKmRzbSA9IDB4MyAmKGRhdGE+PjYpOwogICAgKnpwciA9IDB4NyAmKGRhdGE+PjMpOwogICAgKnpuciA9IDB4NyAmKGRhdGEpOwoKICAgIHJldHVybiBHVF9PSzsKCn0KCgoKCgoKCgoKCgoKCgoKCgo=