LyoKICogZGVmYXVsdF9zdG9yZS5jOiBzdG9yYWdlIHNwYWNlIGZvciBkZWZhdWx0cyAKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwovKiogQGRlZmdyb3VwIGRlZmF1bHRfc3RvcmUgc3RvcmFnZSBzcGFjZSBmb3IgZGVmYXVsdHMgCiAqICBAaW5ncm91cCBsaWJyYXJ5CiAqCiAgICAgICBUaGUgcHVycG9zZSBvZiB0aGUgZGVmYXVsdCBzdG9yYWdlIGlzIHRocmVlLWZvbGQ6CgogICAgICAgMSkgICAgIFRvIGNyZWF0ZSBhIGdsb2JhbCBzdG9yYWdlIHNwYWNlIHdpdGhvdXQgY3JlYXRpbmcgYQogICAgICAgICAgICAgIHdob2xlICBidW5jaCAgb2YgZ2xvYmFsbHkgYWNjZXNzaWJsZSB2YXJpYWJsZXMgb3IgYQogICAgICAgICAgICAgIHdob2xlIGJ1bmNoIG9mIGFjY2VzcyBmdW5jdGlvbnMgdG8gd29yayAgd2l0aCAgbW9yZQogICAgICAgICAgICAgIHByaXZhdGVseSByZXN0cmljdGVkIHZhcmlhYmxlcy4KCiAgICAgICAyKSAgICAgVG8gcHJvdmlkZSBhIHNpbmdsZSBsb2NhdGlvbiB3aGVyZSB0aGUgdGhyZWFkIGxvY2stCiAgICAgICAgICAgICAgaW5nIG5lZWRzIHRvIGJlIGltcGxlbWVudGVkLiBBdCB0aGUgIHRpbWUgIG9mICB0aGlzCiAgICAgICAgICAgICAgd3JpdGluZywgIGhvd2V2ZXIsICB0aHJlYWQgIGxvY2tpbmcgIGlzICBub3QgeWV0IGluCiAgICAgICAgICAgICAgcGxhY2UuCgogICAgICAgMykgICAgIFRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIGNyb3NzIGRlcGVuZGVuY2llcyAgYmV0d2VlbgogICAgICAgICAgICAgIGNvZGUgIHBpZWNlcyB0aGF0IG1heSBvciBtYXkgbm90IGJlIGxpbmtlZCB0b2dldGhlcgogICAgICAgICAgICAgIGluIHRoZSBsb25nIHJ1bi4gVGhpcyBwcm92aWRlcyBmb3IgYSAgc2luZ2xlICBsb2NhLQogICAgICAgICAgICAgIHRpb24gIGluIHdoaWNoIGNvbmZpZ3VyYXRpb24gZGF0YSwgZm9yIGV4YW1wbGUsIGNhbgogICAgICAgICAgICAgIGJlIHN0b3JlZCBmb3IgYSBzZXBhcmF0ZSBzZWN0aW9uIG9mIGNvZGUgIHRoYXQgIG1heQogICAgICAgICAgICAgIG5vdCBiZSBsaW5rZWQgaW4gdG8gdGhlIGFwcGxpY2F0aW9uIGluIHF1ZXN0aW9uLgoKICAgICAgIFRoZSBmdW5jdGlvbnMgZGVmaW5lZCBoZXJlIGltcGxlbWVudCB0aGVzZSBnb2Fscy4KCiAgICAgICBDdXJyZW50bHksIHRocmVlIGRhdGEgdHlwZXMgYXJlIHN1cHBvcnRlZDogYm9vbGVhbnMsIGludGUtCiAgICAgICBnZXJzLCBhbmQgc3RyaW5ncy4gRWFjaCBvZiB0aGVzZSBkYXRhIHR5cGVzIGhhdmUgIHNlcGFyYXRlCiAgICAgICBzdG9yYWdlICBzcGFjZXMuICBJbiAgYWRkaXRpb24sIHRoZSBzdG9yYWdlIHNwYWNlIGZvciBlYWNoCiAgICAgICBkYXRhIHR5cGUgaXMgZGl2aWRlZCBmdXJ0aGVyICBieSAgdGhlICBhcHBsaWNhdGlvbiAgbGV2ZWwuCiAgICAgICBDdXJyZW50bHksICB0aGVyZSAgYXJlICB0d28gIHN0b3JhZ2UgIHNwYWNlcy4gVGhlIGZpcnN0IGlzCiAgICAgICByZXNlcnZlZCBmb3IgIHRoZSAgU05NUCAgbGlicmFyeSAgaXRzZWxmLiAgVGhlICBzZWNvbmQgIGlzCiAgICAgICBpbnRlbmRlZCAgZm9yICB1c2UgIGluIGFwcGxpY2F0aW9ucyBhbmQgaXMgbm90IG1vZGlmaWVkIG9yCiAgICAgICBjaGVja2VkIGJ5IHRoZSBsaWJyYXJ5LCBhbmQsIHRoZXJlZm9yZSwgdGhpcyBpcyB0aGUgIHNwYWNlCiAgICAgICB1c2FibGUgYnkgeW91LgogICAgICAgICAgIAogICAgICAgVGhlc2UgZGVmaW5pdGlvbnMgY29ycmVzcG9uZCB3aXRoIHRoZSAic3RvcmlkIiBhcmd1bWVudCB0byB0aGUgQVBJCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCUkFSWV9JRCAgICAgMAogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lEIDEKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19UT0tFTl9JRCAgICAgICAyCgogICAgICAgVGhlc2UgZGVmaW5pdGlvbnMgY29ycmVzcG9uZCB3aXRoIHRoZSAid2hpY2giIGFyZ3VtZW50IHRvIHRoZSBBUEksCiAgICAgICB3aGVuIHRoZSBzdG9yZWlkIGFyZ3VtZW50IGlzIE5FVFNOTVBfRFNfTElCUkFSWV9JRAoKICAgICAgIGxpYnJhcnkgYm9vbGVhbnMKICAgICAgICAgICAgCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX01JQl9FUlJPUlMgICAgICAgICAgMAogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9TQVZFX01JQl9ERVNDUlMgICAgIDEKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfTUlCX0NPTU1FTlRfVEVSTSAgICAyCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX01JQl9QQVJTRV9MQUJFTCAgICAgMwogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9EVU1QX1BBQ0tFVCAgICAgICAgIDQKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfTE9HX1RJTUVTVEFNUCAgICAgICA1CiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX0RPTlRfUkVBRF9DT05GSUdTICAgNgogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9NSUJfUkVQTEFDRSAgICAgICAgIDcgcmVwbGFjZSBvYmplY3RzIGZyb20gbGF0ZXN0IG1vZHVsZSAKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfUFJJTlRfTlVNRVJJQ19FTlVNICA4IHByaW50IG9ubHkgbnVtZXJpYyBlbnVtIHZhbHVlcwogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9QUklOVF9OVU1FUklDX09JRFMgIDkgcHJpbnQgb25seSBudW1lcmljIGVudW0gdmFsdWVzIAogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9ET05UX0JSRUFLRE9XTl9PSURTIDEwIGRvbnQgcHJpbnQgb2lkIGluZGV4ZXMgc3BlY2lhbGx5IAogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9BTEFSTV9ET05UX1VTRV9TSUcgIDExIGRvbid0IHVzZSB0aGUgYWxhcm0oKSBzaWduYWwgCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX1BSSU5UX0ZVTExfT0lEICAgICAgMTIgcHJpbnQgZnVsbHkgcXVhbGlmaWVkIG9pZHMgCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX1FVSUNLX1BSSU5UICAgICAgICAgMTMgcHJpbnQgdmVyeSBicmllZiBvdXRwdXQgZm9yIHBhcnNpbmcKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfUkFORE9NX0FDQ0VTUyAgICAgICAxNCByYW5kb20gYWNjZXNzIHRvIG9pZCBsYWJlbHMKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfUkVHRVhfQUNDRVNTICAgICAgICAxNSByZWdleCBtYXRjaGluZyB0byBvaWQgbGFiZWxzCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX0RPTlRfQ0hFQ0tfUkFOR0UgICAgMTYgZG9uJ3QgY2hlY2sgdmFsdWVzIGZvciByYW5nZXMgb24gc2VuZAogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9OT19UT0tFTl9XQVJOSU5HUyAgIDE3IG5vIHdhcm4gYWJvdXQgdW5rbm93biBjb25maWcgdG9rZW5zCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX05VTUVSSUNfVElNRVRJQ0tTICAgMTggcHJpbnQgdGltZXRpY2tzIGFzIGEgbnVtYmVyIAogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9FU0NBUEVfUVVPVEVTICAgICAgIDE5IHNoZWxsIGVzY2FwZSBxdW90ZSBtYXJrcyBpbiBvaWRzCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFICAgICAgMjAgZW5jb2RlIHBhY2tldHMgZnJvbSBiYWNrIHRvIGZyb250CiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX1BSSU5UX0JBUkVfVkFMVUUgICAgMjEganVzdCBwcmludCB2YWx1ZSAobm90IE9JRCA9IHZhbHVlKQogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9FWFRFTkRFRF9JTkRFWCAgICAgIDIyIHByaW50IGV4dGVuZGVkIGluZGV4IGZvcm1hdCBbeDFdW3gyXQogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9QUklOVF9IRVhfVEVYVCAgICAgIDIzIHByaW50IEFTQ0lJIHRleHQgYWxvbmcgd2l0aCBoZXggc3RyaW5ncwogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9QUklOVF9VQ0RfU1RZTEVfT0lEIDI0IHByaW50IE9JRCdzIHVzaW5nIHRoZSBVQ0Qtc3R5bGUgcHJlZml4IHN1cHByZXNzaW9uCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX1JFQURfVUNEX1NUWUxFX09JRCAgMjUgcmVxdWlyZSB0b3AtbGV2ZWwgT0lEcyB0byBiZSBwcmVmaXhlZCB3aXRoIGEgZG90CiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX0hBVkVfUkVBRF9QUkVNSUJfQ09ORklHIDI2IGhhdmUgdGhlIHByZS1taWIgcGFyc2luZyBjb25maWcgdG9rZW5zIGJlZW4gcHJvY2Vzc2VkCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX0hBVkVfUkVBRF9DT05GSUcgICAgMjcgaGF2ZSB0aGUgY29uZmlnIHRva2VucyBiZWVuIHByb2Nlc3NlZAogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9RVUlDS0VfUFJJTlQgICAgICAgIDI4CiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX0RPTlRfUFJJTlRfVU5JVFMgICAgMjkgZG9uJ3QgcHJpbnQgVU5JVFMgc3VmZml4CiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX05PX0RJU1BMQVlfSElOVCAgICAgMzAgZG9uJ3QgYXBwbHkgRElTUExBWS1ISU5UcwogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl8xNkJJVF9JRFMgICAgICAgICAgIDMxIHJlc3RyaWN0IHJlcXVlc3RJRHMsIGV0YyB0byAxNi1iaXQgdmFsdWVzCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX0RPTlRfUEVSU0lTVF9TVEFURSAgMzIgZG9uJ3Qgc2F2ZS9sb2FkIGFueSBwZXJzaXN0YW50IHN0YXRlCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCXzJESUdJVF9IRVhfT1VUUFVUICAgMzMgcHJpbnQgYSBsZWFkaW5nIDAgb24gaGV4IHZhbHVlcyA8PSAnZicKCgogICAgICAgbGlicmFyeSBpbnRlZ2VycwoKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfTUlCX1dBUk5JTkdTICAwCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX1NFQ0xFVkVMICAgICAgMQogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9TTk1QVkVSU0lPTiAgIDIKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfREVGQVVMVF9QT1JUICAzCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX09JRF9PVVRQVVRfRk9STUFUICA0CiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX1NUUklOR19PVVRQVVRfRk9STUFUIDUKCiAgICAgICBsaWJyYXJ5IHN0cmluZ3MKCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX1NFQ05BTUUgICAgICAgICAgIDAKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfQ09OVEVYVCAgICAgICAgICAgMQogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9QQVNTUEhSQVNFICAgICAgICAyCiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX0FVVEhQQVNTUEhSQVNFICAgIDMKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfUFJJVlBBU1NQSFJBU0UgICAgNAogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9PUFRJT05BTENPTkZJRyAgICA1CiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUgICAgICAgICAgIDYKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfQ09NTVVOSVRZICAgICAgICAgNwogICAgICAgLSBcI2RlZmluZSBORVRTTk1QX0RTX0xJQl9QRVJTSVNURU5UX0RJUiAgICA4CiAgICAgICAtIFwjZGVmaW5lIE5FVFNOTVBfRFNfTElCX0NPTkZJR1VSQVRJT05fRElSIDkKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfU0VDTU9ERUwgICAgICAgICAgMTAKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfTUlCRElSUyAgICAgICAgICAgMTEKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfT0lEU1VGRklYICAgICAgICAgMTIKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfT0lEUFJFRklYICAgICAgICAgMTMKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfQ0xJRU5UX0FERFIgICAgICAgMTQKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfVEVNUF9GSUxFX1BBVFRFUk4gMTUKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfQVVUSE1BU1RFUktFWSAgICAgMTYKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfUFJJVk1BU1RFUktFWSAgICAgMTcKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfQVVUSExPQ0FMSVpFREtFWSAgMTgKICAgICAgIC0gXCNkZWZpbmUgTkVUU05NUF9EU19MSUJfUFJJVkxPQ0FMSVpFREtFWSAgMTkKCiAqICBAewogKi8KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX1NURExJQl9ICiNpbmNsdWRlIDxzdGRsaWIuaD4KI2VuZGlmCiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKCiNpZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpZiBIQVZFX0RNQUxMT0NfSAojaW5jbHVkZSA8ZG1hbGxvYy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC90eXBlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvb3V0cHV0X2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvY29uZmlnX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9kZWZhdWx0X3N0b3JlLmg+ICAgIC8qIGZvciAiaW50ZXJuYWwiIGRlZmluaXRpb25zICovCiNpbmNsdWRlIDxuZXQtc25tcC91dGlsaXRpZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXBfYXBpLmg+CgpzdGF0aWMgY29uc3QgY2hhciAqIHN0b3JlcyBbTkVUU05NUF9EU19NQVhfSURTXSA9IHsgIkxJQiIsICJBUFAiLCAiVE9LIiB9OwoKdHlwZWRlZiBzdHJ1Y3QgbmV0c25tcF9kc19yZWFkX2NvbmZpZ19zIHsKICB1X2NoYXIgICAgICAgICAgdHlwZTsKICBjaGFyICAgICAgICAgICAqdG9rZW47CiAgY2hhciAgICAgICAgICAgKmZ0eXBlOwogIGludCAgICAgICAgICAgICBzdG9yZWlkOwogIGludCAgICAgICAgICAgICB3aGljaDsKICBzdHJ1Y3QgbmV0c25tcF9kc19yZWFkX2NvbmZpZ19zICpuZXh0Owp9IG5ldHNubXBfZHNfcmVhZF9jb25maWc7CgpzdGF0aWMgbmV0c25tcF9kc19yZWFkX2NvbmZpZyAqbmV0c25tcF9kc19jb25maWdzID0gTlVMTDsKCnN0YXRpYyBpbnQgICBuZXRzbm1wX2RzX2ludGVnZXJzW05FVFNOTVBfRFNfTUFYX0lEU11bTkVUU05NUF9EU19NQVhfU1VCSURTXTsKc3RhdGljIGNoYXIgIG5ldHNubXBfZHNfYm9vbGVhbnNbTkVUU05NUF9EU19NQVhfSURTXVtORVRTTk1QX0RTX01BWF9TVUJJRFMvOF07CnN0YXRpYyBjaGFyICpuZXRzbm1wX2RzX3N0cmluZ3NbTkVUU05NUF9EU19NQVhfSURTXVtORVRTTk1QX0RTX01BWF9TVUJJRFNdOwpzdGF0aWMgdm9pZCAqbmV0c25tcF9kc192b2lkc1tORVRTTk1QX0RTX01BWF9JRFNdW05FVFNOTVBfRFNfTUFYX1NVQklEU107CgovKgogKiBQcm90b3R5cGUgZGVmaW5pdGlvbnMgCiAqLwp2b2lkICAgICAgICAgICAgbmV0c25tcF9kc19oYW5kbGVfY29uZmlnKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpsaW5lKTsKCi8qKgogKiBTdG9yZXMgInRydWUiIG9yICJmYWxzZSIgZ2l2ZW4gYW4gaW50IHZhbHVlIGZvciB2YWx1ZSBpbnRvCiAqIG5ldHNubXBfZHNfYm9vbGVhbnNbc3RvcmVdW3doaWNoXSBzbG90LiAgCiAqCiAqIEBwYXJhbSBzdG9yZWlkIGFuIGluZGV4IHRvIHRoZSBib29sZWFuIHN0b3JhZ2UgY29udGFpbmVyJ3MgZmlyc3QgaW5kZXgoc3RvcmUpCiAqCiAqIEBwYXJhbSB3aGljaCBhbiBpbmRleCB0byB0aGUgYm9vbGVhbiBzdG9yYWdlIGNvbnRhaW5lcidzIHNlY29uZCBpbmRleCh3aGljaCkKICoKICogQHBhcmFtIHZhbHVlIGlmID4gMCwgInRydWUiIGlzIHNldCBpbnRvIHRoZSBzbG90IG90aGVyd2lzZSAiZmFsc2UiCiAqCiAqIEByZXR1cm4gUmV0dXJucyBTTk1QUEVSUl9HRU5FUlIgaWYgdGhlIHN0b3JlaWQgYW5kIHdoaWNoIHBhcmFtZXRlcnMgZG8gbm90CiAqIGNvcnJlc3BvbmQgdG8gYSB2YWxpZCBzbG90LCBvciAgU05NUEVSUl9TVUNDRVNTIG90aGVyd2lzZS4KICovCmludApuZXRzbm1wX2RzX3NldF9ib29sZWFuKGludCBzdG9yZWlkLCBpbnQgd2hpY2gsIGludCB2YWx1ZSkKewogICAgaWYgKHN0b3JlaWQgPCAwIHx8IHN0b3JlaWQgPj0gTkVUU05NUF9EU19NQVhfSURTIHx8IAoJd2hpY2ggICA8IDAgfHwgd2hpY2ggICA+PSBORVRTTk1QX0RTX01BWF9TVUJJRFMpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgREVCVUdNU0dUTCgoIm5ldHNubXBfZHNfc2V0X2Jvb2xlYW4iLCAiU2V0dGluZyAlczolZCA9ICVkLyVzXG4iLAogICAgICAgICAgICAgICAgc3RvcmVzW3N0b3JlaWRdLCB3aGljaCwgdmFsdWUsICgodmFsdWUpID8gIlRydWUiIDogIkZhbHNlIikpKTsKCiAgICBpZiAodmFsdWUgPiAwKSB7CiAgICAgICAgbmV0c25tcF9kc19ib29sZWFuc1tzdG9yZWlkXVt3aGljaC84XSB8PSAoMSA8PCAod2hpY2ggJSA4KSk7CiAgICB9IGVsc2UgewogICAgICAgIG5ldHNubXBfZHNfYm9vbGVhbnNbc3RvcmVpZF1bd2hpY2gvOF0gJj0gKDB4ZmY3ZiA+PiAoNyAtICh3aGljaCAlIDgpKSk7CiAgICB9CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKaW50Cm5ldHNubXBfZHNfdG9nZ2xlX2Jvb2xlYW4oaW50IHN0b3JlaWQsIGludCB3aGljaCkKewogICAgaWYgKHN0b3JlaWQgPCAwIHx8IHN0b3JlaWQgPj0gTkVUU05NUF9EU19NQVhfSURTIHx8IAoJd2hpY2ggICA8IDAgfHwgd2hpY2ggICA+PSBORVRTTk1QX0RTX01BWF9TVUJJRFMpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgaWYgKChuZXRzbm1wX2RzX2Jvb2xlYW5zW3N0b3JlaWRdW3doaWNoLzhdICYgKDEgPDwgKHdoaWNoICUgOCkpKSA9PSAwKSB7CiAgICAgICAgbmV0c25tcF9kc19ib29sZWFuc1tzdG9yZWlkXVt3aGljaC84XSB8PSAoMSA8PCAod2hpY2ggJSA4KSk7CiAgICB9IGVsc2UgewogICAgICAgIG5ldHNubXBfZHNfYm9vbGVhbnNbc3RvcmVpZF1bd2hpY2gvOF0gJj0gKDB4ZmY3ZiA+PiAoNyAtICh3aGljaCAlIDgpKSk7CiAgICB9CgogICAgREVCVUdNU0dUTCgoIm5ldHNubXBfZHNfdG9nZ2xlX2Jvb2xlYW4iLCAiU2V0dGluZyAlczolZCA9ICVkLyVzXG4iLAogICAgICAgICAgICAgICAgc3RvcmVzW3N0b3JlaWRdLCB3aGljaCwgbmV0c25tcF9kc19ib29sZWFuc1tzdG9yZWlkXVt3aGljaC84XSwKICAgICAgICAgICAgICAgICgobmV0c25tcF9kc19ib29sZWFuc1tzdG9yZWlkXVt3aGljaC84XSkgPyAiVHJ1ZSIgOiAiRmFsc2UiKSkpOwoKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCmludApuZXRzbm1wX2RzX2dldF9ib29sZWFuKGludCBzdG9yZWlkLCBpbnQgd2hpY2gpCnsKICAgIGlmIChzdG9yZWlkIDwgMCB8fCBzdG9yZWlkID49IE5FVFNOTVBfRFNfTUFYX0lEUyB8fCAKCXdoaWNoICAgPCAwIHx8IHdoaWNoICAgPj0gTkVUU05NUF9EU19NQVhfU1VCSURTKSB7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIHJldHVybiAobmV0c25tcF9kc19ib29sZWFuc1tzdG9yZWlkXVt3aGljaC84XSAmICgxIDw8ICh3aGljaCAlIDgpKSkgPyAxOjA7Cn0KCmludApuZXRzbm1wX2RzX3NldF9pbnQoaW50IHN0b3JlaWQsIGludCB3aGljaCwgaW50IHZhbHVlKQp7CiAgICBpZiAoc3RvcmVpZCA8IDAgfHwgc3RvcmVpZCA+PSBORVRTTk1QX0RTX01BWF9JRFMgfHwgCgl3aGljaCAgIDwgMCB8fCB3aGljaCAgID49IE5FVFNOTVBfRFNfTUFYX1NVQklEUykgewogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KCiAgICBERUJVR01TR1RMKCgibmV0c25tcF9kc19zZXRfaW50IiwgIlNldHRpbmcgJXM6JWQgPSAlZFxuIiwKICAgICAgICAgICAgICAgIHN0b3Jlc1tzdG9yZWlkXSwgd2hpY2gsIHZhbHVlKSk7CgogICAgbmV0c25tcF9kc19pbnRlZ2Vyc1tzdG9yZWlkXVt3aGljaF0gPSB2YWx1ZTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCmludApuZXRzbm1wX2RzX2dldF9pbnQoaW50IHN0b3JlaWQsIGludCB3aGljaCkKewogICAgaWYgKHN0b3JlaWQgPCAwIHx8IHN0b3JlaWQgPj0gTkVUU05NUF9EU19NQVhfSURTIHx8IAoJd2hpY2ggICA8IDAgfHwgd2hpY2ggICA+PSBORVRTTk1QX0RTX01BWF9TVUJJRFMpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgcmV0dXJuIG5ldHNubXBfZHNfaW50ZWdlcnNbc3RvcmVpZF1bd2hpY2hdOwp9CgppbnQKbmV0c25tcF9kc19zZXRfc3RyaW5nKGludCBzdG9yZWlkLCBpbnQgd2hpY2gsIGNvbnN0IGNoYXIgKnZhbHVlKQp7CiAgICBpZiAoc3RvcmVpZCA8IDAgfHwgc3RvcmVpZCA+PSBORVRTTk1QX0RTX01BWF9JRFMgfHwgCgl3aGljaCAgIDwgMCB8fCB3aGljaCAgID49IE5FVFNOTVBfRFNfTUFYX1NVQklEUykgewogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KCiAgICBERUJVR01TR1RMKCgibmV0c25tcF9kc19zZXRfc3RyaW5nIiwgIlNldHRpbmcgJXM6JWQgPSBcIiVzXCJcbiIsCiAgICAgICAgICAgICAgICBzdG9yZXNbc3RvcmVpZF0sIHdoaWNoLCAodmFsdWUgPyB2YWx1ZSA6ICIobnVsbCkiKSkpOwoKICAgIC8qCiAgICAgKiBpcyBzb21lIHNpbGx5IHBlcnNvbiBpcyBjYWxsaW5nIHVzIHdpdGggb3VyIG93biBwb2ludGVyPwogICAgICovCiAgICBpZiAobmV0c25tcF9kc19zdHJpbmdzW3N0b3JlaWRdW3doaWNoXSA9PSB2YWx1ZSkKICAgICAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwogICAgCiAgICBpZiAobmV0c25tcF9kc19zdHJpbmdzW3N0b3JlaWRdW3doaWNoXSAhPSBOVUxMKSB7CiAgICAgICAgZnJlZShuZXRzbm1wX2RzX3N0cmluZ3Nbc3RvcmVpZF1bd2hpY2hdKTsKCW5ldHNubXBfZHNfc3RyaW5nc1tzdG9yZWlkXVt3aGljaF0gPSBOVUxMOwogICAgfQoKICAgIGlmICh2YWx1ZSkgewogICAgICAgIG5ldHNubXBfZHNfc3RyaW5nc1tzdG9yZWlkXVt3aGljaF0gPSBzdHJkdXAodmFsdWUpOwogICAgfSBlbHNlIHsKICAgICAgICBuZXRzbm1wX2RzX3N0cmluZ3Nbc3RvcmVpZF1bd2hpY2hdID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgpjaGFyICoKbmV0c25tcF9kc19nZXRfc3RyaW5nKGludCBzdG9yZWlkLCBpbnQgd2hpY2gpCnsKICAgIGlmIChzdG9yZWlkIDwgMCB8fCBzdG9yZWlkID49IE5FVFNOTVBfRFNfTUFYX0lEUyB8fCAKCXdoaWNoICAgPCAwIHx8IHdoaWNoICAgPj0gTkVUU05NUF9EU19NQVhfU1VCSURTKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIG5ldHNubXBfZHNfc3RyaW5nc1tzdG9yZWlkXVt3aGljaF07Cn0KCmludApuZXRzbm1wX2RzX3NldF92b2lkKGludCBzdG9yZWlkLCBpbnQgd2hpY2gsIHZvaWQgKnZhbHVlKQp7CiAgICBpZiAoc3RvcmVpZCA8IDAgfHwgc3RvcmVpZCA+PSBORVRTTk1QX0RTX01BWF9JRFMgfHwgCgl3aGljaCAgIDwgMCB8fCB3aGljaCAgID49IE5FVFNOTVBfRFNfTUFYX1NVQklEUykgewogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KCiAgICBERUJVR01TR1RMKCgibmV0c25tcF9kc19zZXRfdm9pZCIsICJTZXR0aW5nICVzOiVkID0gJXBcbiIsCiAgICAgICAgICAgICAgICBzdG9yZXNbc3RvcmVpZF0sIHdoaWNoLCB2YWx1ZSkpOwoKICAgIG5ldHNubXBfZHNfdm9pZHNbc3RvcmVpZF1bd2hpY2hdID0gdmFsdWU7CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKdm9pZCAqCm5ldHNubXBfZHNfZ2V0X3ZvaWQoaW50IHN0b3JlaWQsIGludCB3aGljaCkKewogICAgaWYgKHN0b3JlaWQgPCAwIHx8IHN0b3JlaWQgPj0gTkVUU05NUF9EU19NQVhfSURTIHx8IAoJd2hpY2ggICA8IDAgfHwgd2hpY2ggICA+PSBORVRTTk1QX0RTX01BWF9TVUJJRFMpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gbmV0c25tcF9kc192b2lkc1tzdG9yZWlkXVt3aGljaF07Cn0KCmludApuZXRzbm1wX2RzX3BhcnNlX2Jvb2xlYW4oY2hhciAqbGluZSkKewogICAgY2hhciAgICAgICAgICAgKnZhbHVlLCAqZW5kcHRyOwogICAgaW50ICAgICAgICAgICAgIGl0bXA7CiAgICBjaGFyICAgICAgICAgICAqc3Q7CgogICAgdmFsdWUgPSBzdHJ0b2tfcihsaW5lLCAiIFx0XG4iLCAmc3QpOwogICAgaWYgKHN0cmNhc2VjbXAodmFsdWUsICJ5ZXMiKSA9PSAwIHx8IAoJc3RyY2FzZWNtcCh2YWx1ZSwgInRydWUiKSA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9IGVsc2UgaWYgKHN0cmNhc2VjbXAodmFsdWUsICJubyIpID09IDAgfHwKCSAgICAgICBzdHJjYXNlY21wKHZhbHVlLCAiZmFsc2UiKSA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9IGVsc2UgewogICAgICAgIGl0bXAgPSBzdHJ0b2wodmFsdWUsICZlbmRwdHIsIDEwKTsKICAgICAgICBpZiAoKmVuZHB0ciAhPSAwIHx8IGl0bXAgPCAwIHx8IGl0bXAgPiAxKSB7CiAgICAgICAgICAgIGNvbmZpZ19wZXJyb3IoIlNob3VsZCBiZSB5ZXN8bm98dHJ1ZXxmYWxzZXwwfDEiKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwoJfQogICAgICAgIHJldHVybiBpdG1wOwogICAgfQp9Cgp2b2lkCm5ldHNubXBfZHNfaGFuZGxlX2NvbmZpZyhjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqbGluZSkKewogICAgbmV0c25tcF9kc19yZWFkX2NvbmZpZyAqZHJzcDsKICAgIGNoYXIgICAgICAgICAgICBidWZbU05NUF9NQVhCVUZdOwogICAgY2hhciAgICAgICAgICAgKnZhbHVlLCAqZW5kcHRyOwogICAgaW50ICAgICAgICAgICAgIGl0bXA7CiAgICBjaGFyICAgICAgICAgICAqc3Q7CgogICAgREVCVUdNU0dUTCgoIm5ldHNubXBfZHNfaGFuZGxlX2NvbmZpZyIsICJoYW5kbGluZyAlc1xuIiwgdG9rZW4pKTsKCiAgICBmb3IgKGRyc3AgPSBuZXRzbm1wX2RzX2NvbmZpZ3M7CiAgICAgICAgIGRyc3AgIT0gTlVMTCAmJiBzdHJjYXNlY21wKHRva2VuLCBkcnNwLT50b2tlbikgIT0gMDsKICAgICAgICAgZHJzcCA9IGRyc3AtPm5leHQpOwoKICAgIGlmIChkcnNwICE9IE5VTEwpIHsKICAgICAgICBERUJVR01TR1RMKCgibmV0c25tcF9kc19oYW5kbGVfY29uZmlnIiwKICAgICAgICAgICAgICAgICAgICAic2V0dGluZzogdG9rZW49JXMsIHR5cGU9JWQsIGlkPSVzLCB3aGljaD0lZFxuIiwKICAgICAgICAgICAgICAgICAgICBkcnNwLT50b2tlbiwgZHJzcC0+dHlwZSwgc3RvcmVzW2Ryc3AtPnN0b3JlaWRdLAogICAgICAgICAgICAgICAgICAgIGRyc3AtPndoaWNoKSk7CgogICAgICAgIHN3aXRjaCAoZHJzcC0+dHlwZSkgewogICAgICAgIGNhc2UgQVNOX0JPT0xFQU46CiAgICAgICAgICAgIGl0bXAgPSBuZXRzbm1wX2RzX3BhcnNlX2Jvb2xlYW4obGluZSk7CiAgICAgICAgICAgIGlmICggaXRtcCAhPSAtMSApCiAgICAgICAgICAgICAgICBuZXRzbm1wX2RzX3NldF9ib29sZWFuKGRyc3AtPnN0b3JlaWQsIGRyc3AtPndoaWNoLCBpdG1wKTsKICAgICAgICAgICAgREVCVUdNU0dUTCgoIm5ldHNubXBfZHNfaGFuZGxlX2NvbmZpZyIsICJib29sOiAlZFxuIiwgaXRtcCkpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBBU05fSU5URUdFUjoKICAgICAgICAgICAgdmFsdWUgPSBzdHJ0b2tfcihsaW5lLCAiIFx0XG4iLCAmc3QpOwogICAgICAgICAgICBpdG1wID0gc3RydG9sKHZhbHVlLCAmZW5kcHRyLCAxMCk7CiAgICAgICAgICAgIGlmICgqZW5kcHRyICE9IDApIHsKICAgICAgICAgICAgICAgIGNvbmZpZ19wZXJyb3IoIkJhZCBpbnRlZ2VyIHZhbHVlIik7CgkgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG5ldHNubXBfZHNfc2V0X2ludChkcnNwLT5zdG9yZWlkLCBkcnNwLT53aGljaCwgaXRtcCk7CgkgICAgfQogICAgICAgICAgICBERUJVR01TR1RMKCgibmV0c25tcF9kc19oYW5kbGVfY29uZmlnIiwgImludDogJWRcbiIsIGl0bXApKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgQVNOX09DVEVUX1NUUjoKICAgICAgICAgICAgaWYgKCpsaW5lID09ICciJykgewogICAgICAgICAgICAgICAgY29weV9ud29yZChsaW5lLCBidWYsIHNpemVvZihidWYpKTsKICAgICAgICAgICAgICAgIG5ldHNubXBfZHNfc2V0X3N0cmluZyhkcnNwLT5zdG9yZWlkLCBkcnNwLT53aGljaCwgYnVmKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG5ldHNubXBfZHNfc2V0X3N0cmluZyhkcnNwLT5zdG9yZWlkLCBkcnNwLT53aGljaCwgbGluZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgREVCVUdNU0dUTCgoIm5ldHNubXBfZHNfaGFuZGxlX2NvbmZpZyIsICJzdHJpbmc6ICVzXG4iLCBsaW5lKSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9kc19oYW5kbGVfY29uZmlnOiB0eXBlICVkICgweCUwMngpXG4iLAogICAgICAgICAgICAgICAgICAgICBkcnNwLT50eXBlLCBkcnNwLT50eXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9kc19oYW5kbGVfY29uZmlnOiBubyByZWdpc3RyYXRpb24gZm9yICVzXG4iLAogICAgICAgICAgICAgICAgIHRva2VuKTsKICAgIH0KfQoKCmludApuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyh1X2NoYXIgdHlwZSwgY29uc3QgY2hhciAqZnR5cGUsIGNvbnN0IGNoYXIgKnRva2VuLAoJCQkgICBpbnQgc3RvcmVpZCwgaW50IHdoaWNoKQp7CiAgICBuZXRzbm1wX2RzX3JlYWRfY29uZmlnICpkcnNwOwoKICAgIGlmIChzdG9yZWlkIDwgMCB8fCBzdG9yZWlkID49IE5FVFNOTVBfRFNfTUFYX0lEUyAgICB8fCAKCXdoaWNoICAgPCAwIHx8IHdoaWNoICAgPj0gTkVUU05NUF9EU19NQVhfU1VCSURTIHx8IHRva2VuID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgaWYgKG5ldHNubXBfZHNfY29uZmlncyA9PSBOVUxMKSB7CiAgICAgICAgbmV0c25tcF9kc19jb25maWdzID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2RzX3JlYWRfY29uZmlnKTsKICAgICAgICBpZiAobmV0c25tcF9kc19jb25maWdzID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICBkcnNwID0gbmV0c25tcF9kc19jb25maWdzOwogICAgfSBlbHNlIHsKICAgICAgICBmb3IgKGRyc3AgPSBuZXRzbm1wX2RzX2NvbmZpZ3M7IGRyc3AtPm5leHQgIT0gTlVMTDsgZHJzcCA9IGRyc3AtPm5leHQpOwogICAgICAgIGRyc3AtPm5leHQgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfZHNfcmVhZF9jb25maWcpOwogICAgICAgIGlmIChkcnNwLT5uZXh0ID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICBkcnNwID0gZHJzcC0+bmV4dDsKICAgIH0KCiAgICBkcnNwLT50eXBlICAgID0gdHlwZTsKICAgIGRyc3AtPmZ0eXBlICAgPSBzdHJkdXAoZnR5cGUpOwogICAgZHJzcC0+dG9rZW4gICA9IHN0cmR1cCh0b2tlbik7CiAgICBkcnNwLT5zdG9yZWlkID0gc3RvcmVpZDsKICAgIGRyc3AtPndoaWNoICAgPSB3aGljaDsKCiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgQVNOX0JPT0xFQU46CiAgICAgICAgcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoZnR5cGUsIHRva2VuLCBuZXRzbm1wX2RzX2hhbmRsZV9jb25maWcsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigxfHllc3x0cnVlfDB8bm98ZmFsc2UpIik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBBU05fSU5URUdFUjoKICAgICAgICByZWdpc3Rlcl9jb25maWdfaGFuZGxlcihmdHlwZSwgdG9rZW4sIG5ldHNubXBfZHNfaGFuZGxlX2NvbmZpZywgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW50ZWdlclZhbHVlIik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBBU05fT0NURVRfU1RSOgogICAgICAgIHJlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKGZ0eXBlLCB0b2tlbiwgbmV0c25tcF9kc19oYW5kbGVfY29uZmlnLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdHJpbmciKTsKICAgICAgICBicmVhazsKCiAgICB9CiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgppbnQKbmV0c25tcF9kc19yZWdpc3Rlcl9wcmVtaWIodV9jaGFyIHR5cGUsIGNvbnN0IGNoYXIgKmZ0eXBlLCBjb25zdCBjaGFyICp0b2tlbiwKCQkJICAgaW50IHN0b3JlaWQsIGludCB3aGljaCkKewogICAgbmV0c25tcF9kc19yZWFkX2NvbmZpZyAqZHJzcDsKCiAgICBpZiAoc3RvcmVpZCA8IDAgfHwgc3RvcmVpZCA+PSBORVRTTk1QX0RTX01BWF9JRFMgICAgfHwgCgl3aGljaCAgIDwgMCB8fCB3aGljaCAgID49IE5FVFNOTVBfRFNfTUFYX1NVQklEUyB8fCB0b2tlbiA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIGlmIChuZXRzbm1wX2RzX2NvbmZpZ3MgPT0gTlVMTCkgewogICAgICAgIG5ldHNubXBfZHNfY29uZmlncyA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9kc19yZWFkX2NvbmZpZyk7CiAgICAgICAgaWYgKG5ldHNubXBfZHNfY29uZmlncyA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgZHJzcCA9IG5ldHNubXBfZHNfY29uZmlnczsKICAgIH0gZWxzZSB7CiAgICAgICAgZm9yIChkcnNwID0gbmV0c25tcF9kc19jb25maWdzOyBkcnNwLT5uZXh0ICE9IE5VTEw7IGRyc3AgPSBkcnNwLT5uZXh0KTsKICAgICAgICBkcnNwLT5uZXh0ID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2RzX3JlYWRfY29uZmlnKTsKICAgICAgICBpZiAoZHJzcC0+bmV4dCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgZHJzcCA9IGRyc3AtPm5leHQ7CiAgICB9CgogICAgZHJzcC0+dHlwZSAgICA9IHR5cGU7CiAgICBkcnNwLT5mdHlwZSAgID0gc3RyZHVwKGZ0eXBlKTsKICAgIGRyc3AtPnRva2VuICAgPSBzdHJkdXAodG9rZW4pOwogICAgZHJzcC0+c3RvcmVpZCA9IHN0b3JlaWQ7CiAgICBkcnNwLT53aGljaCAgID0gd2hpY2g7CgogICAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIEFTTl9CT09MRUFOOgogICAgICAgIHJlZ2lzdGVyX3ByZW5ldHNubXBfbWliX2hhbmRsZXIoZnR5cGUsIHRva2VuLCBuZXRzbm1wX2RzX2hhbmRsZV9jb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAiKDF8eWVzfHRydWV8MHxub3xmYWxzZSkiKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEFTTl9JTlRFR0VSOgogICAgICAgIHJlZ2lzdGVyX3ByZW5ldHNubXBfbWliX2hhbmRsZXIoZnR5cGUsIHRva2VuLCBuZXRzbm1wX2RzX2hhbmRsZV9jb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAiaW50ZWdlclZhbHVlIik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBBU05fT0NURVRfU1RSOgogICAgICAgIHJlZ2lzdGVyX3ByZW5ldHNubXBfbWliX2hhbmRsZXIoZnR5cGUsIHRva2VuLCBuZXRzbm1wX2RzX2hhbmRsZV9jb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAic3RyaW5nIik7CiAgICAgICAgYnJlYWs7CgogICAgfQogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKdm9pZApuZXRzbm1wX2RzX3NodXRkb3duKHZvaWQpCnsKICAgIG5ldHNubXBfZHNfcmVhZF9jb25maWcgKmRyc3A7CiAgICBpbnQgICAgICAgICAgICAgaSwgajsKCiAgICBmb3IgKGRyc3AgPSBuZXRzbm1wX2RzX2NvbmZpZ3M7IGRyc3A7IGRyc3AgPSBuZXRzbm1wX2RzX2NvbmZpZ3MpIHsKICAgICAgICBuZXRzbm1wX2RzX2NvbmZpZ3MgPSBkcnNwLT5uZXh0OwoKICAgICAgICBpZiAoZHJzcC0+ZnR5cGUgJiYgZHJzcC0+dG9rZW4pIHsKICAgICAgICAgICAgdW5yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihkcnNwLT5mdHlwZSwgZHJzcC0+dG9rZW4pOwogICAgICAgIH0KCWlmIChkcnNwLT5mdHlwZSAhPSBOVUxMKSB7CgkgICAgZnJlZShkcnNwLT5mdHlwZSk7Cgl9CglpZiAoZHJzcC0+dG9rZW4gIT0gTlVMTCkgewoJICAgIGZyZWUoZHJzcC0+dG9rZW4pOwoJfQogICAgICAgIGZyZWUoZHJzcCk7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IE5FVFNOTVBfRFNfTUFYX0lEUzsgaSsrKSB7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IE5FVFNOTVBfRFNfTUFYX1NVQklEUzsgaisrKSB7CiAgICAgICAgICAgIGlmIChuZXRzbm1wX2RzX3N0cmluZ3NbaV1bal0gIT0gTlVMTCkgewogICAgICAgICAgICAgICAgZnJlZShuZXRzbm1wX2RzX3N0cmluZ3NbaV1bal0pOwogICAgICAgICAgICAgICAgbmV0c25tcF9kc19zdHJpbmdzW2ldW2pdID0gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQovKiogIEB9ICovCg==