LyoKICogIHJlYWRwcm9maWxlLmMgLSB1c2VkIHRvIHJlYWQgL3Byb2MvcHJvZmlsZQogKgogKiAgQ29weXJpZ2h0IChDKSAxOTk0LDE5OTYgQWxlc3NhbmRybyBSdWJpbmkgKHJ1YmluaUBpcHZ2aXMudW5pcHYuaXQpCiAqCiAqICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiAgIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqICAgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiAgIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogICBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogICBGb3VuZGF0aW9uLCBJbmMuLCA2NzUgTWFzcyBBdmUsIENhbWJyaWRnZSwgTUEgMDIxMzksIFVTQS4KICovCgovKgogKiAxOTk5LTAyLTIyIEFya2FkaXVzeiBNabZraWV3aWN6IDxtaXNpZWtAcGxkLk9SRy5QTD4KICogLSBhZGRlZCBOYXRpdmUgTGFuZ3VhZ2UgU3VwcG9ydAogKiAxOTk5LTA5LTAxIFN0ZXBoYW5lIEVyYW5pYW4gPGVyYW5pYW5AY2VsbG8uaHBsLmhwLmNvbT4KICogLSA2NGJpdCBjbGVhbiBwYXRjaAogKiAzRmViMjAwMSBBbmRyZXcgTW9ydG9uIDxhbmRyZXdtQHVvdy5lZHUuYXU+CiAqIC0gLU0gb3B0aW9uIHRvIHdyaXRlIHByb2ZpbGUgbXVsdGlwbGllci4KICogMjAwMS0xMS0wNyBXZXJuZXIgQWxtZXNiZXJnZXIgPHdhQGFsbWVzYmVyZ2VyLm5ldD4KICogLSBieXRlIG9yZGVyIGF1dG8tZGV0ZWN0aW9uIGFuZCAtbiBvcHRpb24KICogMjAwMS0xMS0wOSBXZXJuZXIgQWxtZXNiZXJnZXIgPHdhQGFsbWVzYmVyZ2VyLm5ldD4KICogLSBza2lwIHN0ZXAgc2l6ZSAoaW5kZXggMCkKICogMjAwMi0wMy0wOSBKb2huIExldm9uIDxtb3pAY29tcHNvYy5tYW4uYWMudWs+CiAqIC0gbWFrZSBtYXBsaW5lbm8gZG8gc29tZXRoaW5nCiAqIDIwMDItMTEtMjggTWFkcyBNYXJ0aW4gSm9lcmdlbnNlbiArCiAqIC0gYWxzbyB0cnkgL2Jvb3QvU3lzdGVtLm1hcC1gdW5hbWUgLXJgCiAqIDIwMDMtMDQtMDkgV2VybmVyIEFsbWVzYmVyZ2VyIDx3YUBhbG1lc2Jlcmdlci5uZXQ+CiAqIC0gZml4ZWQgb2ZmLWJ5IGVpZ2h0IGVycm9yIGFuZCBpbXByb3ZlZCBoZXVyaXN0aWNzIGluIGJ5dGUgb3JkZXIgZGV0ZWN0aW9uCiAqIDIwMDMtMDgtMTIgTmlraXRhIERhbmlsb3YgPE5pa2l0YUBOYW1lc3lzLkNPTT4KICogLSBhZGRlZCAtcyBvcHRpb247IGV4YW1wbGUgb2YgdXNlOgogKiAicmVhZHByb2ZpbGUgLXMgLW0gL2Jvb3QvU3lzdGVtLm1hcC10ZXN0IHwgZ3JlcCBfX2RfbG9va3VwIHwgc29ydCAtbiAtazMiCiAqCiAqIFRha2VuIGZyb20gdXRpbC1saW51eCBhbmQgYWRhcHRlZCBmb3IgYnVzeWJveCBieQogKiBQYXVsIE11bmR0IDxsZXRoYWxAbGludXgtc2gub3JnPi4KICovCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL3V0c25hbWUuaD4KCiNpbmNsdWRlICJidXN5Ym94LmgiCgojZGVmaW5lIFNfTEVOIDEyOAoKLyogVGhlc2UgYXJlIHRoZSBkZWZhdWx0cyAqLwpzdGF0aWMgY29uc3QgY2hhciBkZWZhdWx0bWFwW109Ii9ib290L1N5c3RlbS5tYXAiOwpzdGF0aWMgY29uc3QgY2hhciBkZWZhdWx0cHJvW109Ii9wcm9jL3Byb2ZpbGUiOwoKaW50IHJlYWRwcm9maWxlX21haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KQp7CglGSUxFICptYXA7CglpbnQgcHJvRmQ7Cgljb25zdCBjaGFyICptYXBGaWxlLCAqcHJvRmlsZSwgKm11bHQ9MDsKCXVuc2lnbmVkIGxvbmcgbGVuPTAsIGluZHg9MTsKCXVuc2lnbmVkIGxvbmcgbG9uZyBhZGQwPTA7Cgl1bnNpZ25lZCBpbnQgc3RlcDsKCXVuc2lnbmVkIGludCAqYnVmLCB0b3RhbCwgZm5fbGVuOwoJdW5zaWduZWQgbG9uZyBsb25nIGZuX2FkZCwgbmV4dF9hZGQ7ICAgICAgICAgIC8qIGN1cnJlbnQgYW5kIG5leHQgYWRkcmVzcyAqLwoJY2hhciBmbl9uYW1lW1NfTEVOXSwgbmV4dF9uYW1lW1NfTEVOXTsgICAvKiBjdXJyZW50IGFuZCBuZXh0IG5hbWUgKi8KCWNoYXIgbW9kZVs4XTsKCWludCBjOwoJaW50IG9wdEFsbD0wLCBvcHRJbmZvPTAsIG9wdFJlc2V0PTAsIG9wdFZlcmJvc2U9MCwgb3B0TmF0aXZlPTA7CglpbnQgb3B0Qmlucz0wLCBvcHRTdWI9MDsKCWNoYXIgbWFwbGluZVtTX0xFTl07CglpbnQgbWFwbGluZW5vPTE7CglpbnQgaGVhZGVyX3ByaW50ZWQ7CgojZGVmaW5lIG5leHQgKGN1cnJlbnReMSkKCglwcm9GaWxlID0gZGVmYXVsdHBybzsKCW1hcEZpbGUgPSBkZWZhdWx0bWFwOwoKCXdoaWxlICgoYyA9IGdldG9wdChhcmdjLCBhcmd2LCAiTTptOm5wOml0dmFyVmJzIikpICE9IC0xKSB7CgkJc3dpdGNoKGMpIHsKCQljYXNlICdtJzoKCQkJbWFwRmlsZSA9IG9wdGFyZzsKCQkJYnJlYWs7CgkJY2FzZSAnbic6CgkJCW9wdE5hdGl2ZSsrOwoJCQlicmVhazsKCQljYXNlICdwJzoKCQkJcHJvRmlsZSA9IG9wdGFyZzsKCQkJYnJlYWs7CgkJY2FzZSAnYSc6CgkJCW9wdEFsbCsrOwoJCQlicmVhazsKCQljYXNlICdiJzoKCQkJb3B0QmlucysrOwoJCQlicmVhazsKCQljYXNlICdzJzoKCQkJb3B0U3ViKys7CgkJCWJyZWFrOwoJCWNhc2UgJ2knOgoJCQlvcHRJbmZvKys7CgkJCWJyZWFrOwoJCWNhc2UgJ00nOgoJCQltdWx0ID0gb3B0YXJnOwoJCQlicmVhazsKCQljYXNlICdyJzoKCQkJb3B0UmVzZXQrKzsKCQkJYnJlYWs7CgkJY2FzZSAndic6CgkJCW9wdFZlcmJvc2UrKzsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJYmJfc2hvd191c2FnZSgpOwoJCX0KCX0KCglpZiAob3B0UmVzZXQgfHwgbXVsdCkgewoJCWludCBtdWx0aXBsaWVyLCBmZCwgdG9fd3JpdGU7CgoJCS8qCgkJICogV2hlbiB3cml0aW5nIHRoZSBtdWx0aXBsaWVyLCBpZiB0aGUgbGVuZ3RoIG9mIHRoZSB3cml0ZSBpcwoJCSAqIG5vdCBzaXplb2YoaW50KSwgdGhlIG11bHRpcGxpZXIgaXMgbm90IGNoYW5nZWQKCQkgKi8KCQlpZiAobXVsdCkgewoJCQltdWx0aXBsaWVyID0gc3RydG91bChtdWx0LCAwLCAxMCk7CgkJCXRvX3dyaXRlID0gc2l6ZW9mKGludCk7CgkJfSBlbHNlIHsKCQkJbXVsdGlwbGllciA9IDA7CgkJCXRvX3dyaXRlID0gMTsJLyogc3RoIGRpZmZlcmVudCBmcm9tIHNpemVvZihpbnQpICovCgkJfQoKCQlmZCA9IGJiX3hvcGVuKGRlZmF1bHRwcm8sT19XUk9OTFkpOwoKCQlpZiAod3JpdGUoZmQsICZtdWx0aXBsaWVyLCB0b193cml0ZSkgIT0gdG9fd3JpdGUpCgkJCWJiX3BlcnJvcl9tc2dfYW5kX2RpZSgiZXJyb3Igd3JpdGluZyAlcyIsIGRlZmF1bHRwcm8pOwoKCQljbG9zZShmZCk7CgkJcmV0dXJuIEVYSVRfU1VDQ0VTUzsKCX0KCgkvKgoJICogVXNlIGFuIGZkIGZvciB0aGUgcHJvZmlsaW5nIGJ1ZmZlciwgdG8gc2tpcCBzdGRpbyBvdmVyaGVhZAoJICovCgoJcHJvRmQgPSBiYl94b3Blbihwcm9GaWxlLE9fUkRPTkxZKTsKCglpZiAoKChpbnQpKGxlbj1sc2Vlayhwcm9GZCwwLFNFRUtfRU5EKSkgPCAwKQoJICAgIHx8IChsc2Vlayhwcm9GZCwwLFNFRUtfU0VUKSA8IDApKQoJCWJiX3BlcnJvcl9tc2dfYW5kX2RpZShwcm9GaWxlKTsKCglidWYgPSB4bWFsbG9jKGxlbik7CgoJaWYgKHJlYWQocHJvRmQsYnVmLGxlbikgIT0gbGVuKQoJCWJiX3BlcnJvcl9tc2dfYW5kX2RpZShwcm9GaWxlKTsKCgljbG9zZShwcm9GZCk7CgoJaWYgKCFvcHROYXRpdmUpIHsKCQlpbnQgZW50cmllcyA9IGxlbi9zaXplb2YoKmJ1Zik7CgkJaW50IGJpZyA9IDAsc21hbGwgPSAwLGk7CgkJdW5zaWduZWQgKnA7CgoJCWZvciAocCA9IGJ1ZisxOyBwIDwgYnVmK2VudHJpZXM7IHArKykgewoJCQlpZiAoKnAgJiB+MFUgPDwgKHNpemVvZigqYnVmKSo0KSkKCQkJCWJpZysrOwoJCQlpZiAoKnAgJiAoKDEgPDwgKHNpemVvZigqYnVmKSo0KSktMSkpCgkJCQlzbWFsbCsrOwoJCX0KCQlpZiAoYmlnID4gc21hbGwpIHsKCQkJYmJfZXJyb3JfbXNnKCJBc3N1bWluZyByZXZlcnNlZCBieXRlIG9yZGVyLiAiCgkJCQkiVXNlIC1uIHRvIGZvcmNlIG5hdGl2ZSBieXRlIG9yZGVyLiIpOwoJCQlmb3IgKHAgPSBidWY7IHAgPCBidWYrZW50cmllczsgcCsrKQoJCQkJZm9yIChpID0gMDsgaSA8IHNpemVvZigqYnVmKS8yOyBpKyspIHsKCQkJCQl1bnNpZ25lZCBjaGFyICpiID0gKHVuc2lnbmVkIGNoYXIgKikgcDsKCQkJCQl1bnNpZ25lZCBjaGFyIHRtcDsKCgkJCQkJdG1wID0gYltpXTsKCQkJCQliW2ldID0gYltzaXplb2YoKmJ1ZiktaS0xXTsKCQkJCQliW3NpemVvZigqYnVmKS1pLTFdID0gdG1wOwoJCQkJfQoJCX0KCX0KCglzdGVwID0gYnVmWzBdOwoJaWYgKG9wdEluZm8pIHsKCQlwcmludGYoIlNhbXBsaW5nX3N0ZXA6ICVpXG4iLCBzdGVwKTsKCQlyZXR1cm4gRVhJVF9TVUNDRVNTOwoJfQoKCXRvdGFsID0gMDsKCgltYXAgPSBiYl94Zm9wZW4obWFwRmlsZSwgInIiKTsKCgl3aGlsZSAoZmdldHMobWFwbGluZSxTX0xFTixtYXApKSB7CgkJaWYgKHNzY2FuZihtYXBsaW5lLCIlbGx4ICVzICVzIiwmZm5fYWRkLG1vZGUsZm5fbmFtZSkgIT0gMykKCQkJYmJfZXJyb3JfbXNnX2FuZF9kaWUoIiVzKCVpKTogd3JvbmcgbWFwIGxpbmUiLAoJCQkJCSAgICAgbWFwRmlsZSwgbWFwbGluZW5vKTsKCgkJaWYgKCFzdHJjbXAoZm5fbmFtZSwiX3N0ZXh0IikpIC8qIG9ubHkgZWxmIHdvcmtzIGxpa2UgdGhpcyAqLyB7CgkJCWFkZDAgPSBmbl9hZGQ7CgkJCWJyZWFrOwoJCX0KCQltYXBsaW5lbm8rKzsKCX0KCglpZiAoIWFkZDApCgkJYmJfZXJyb3JfbXNnX2FuZF9kaWUoImNhbid0IGZpbmQgXCJfc3RleHRcIiBpbiAlcyIsIG1hcEZpbGUpOwoKCS8qCgkgKiBNYWluIGxvb3AuCgkgKi8KCXdoaWxlIChmZ2V0cyhtYXBsaW5lLFNfTEVOLG1hcCkpIHsKCQl1bnNpZ25lZCBpbnQgdGhpcyA9IDA7CgoJCWlmIChzc2NhbmYobWFwbGluZSwiJWxseCAlcyAlcyIsJm5leHRfYWRkLG1vZGUsbmV4dF9uYW1lKSAhPSAzKQoJCQliYl9lcnJvcl9tc2dfYW5kX2RpZSgiJXMoJWkpOiB3cm9uZyBtYXAgbGluZSIsCgkJCQkJICAgICBtYXBGaWxlLCBtYXBsaW5lbm8pOwoKCQloZWFkZXJfcHJpbnRlZCA9IDA7CgoJCS8qIGlnbm9yZSBhbnkgTEVBRElORyAoYmVmb3JlIGEgJ1t0VF0nIHN5bWJvbCBpcyBmb3VuZCkKCQkgICBBYnNvbHV0ZSBzeW1ib2xzICovCgkJaWYgKCgqbW9kZSA9PSAnQScgfHwgKm1vZGUgPT0gJz8nKSAmJiB0b3RhbCA9PSAwKSBjb250aW51ZTsKCQlpZiAoKm1vZGUgIT0gJ1QnICYmICptb2RlICE9ICd0JyAmJgoJCSAgICAqbW9kZSAhPSAnVycgJiYgKm1vZGUgIT0gJ3cnKQoJCQlicmVhazsJLyogb25seSB0ZXh0IGlzIHByb2ZpbGVkICovCgoJCWlmIChpbmR4ID49IGxlbiAvIHNpemVvZigqYnVmKSkKCQkJYmJfZXJyb3JfbXNnX2FuZF9kaWUoInByb2ZpbGUgYWRkcmVzcyBvdXQgb2YgcmFuZ2UuICIKCQkJCQkgICAgICJXcm9uZyBtYXAgZmlsZT8iKTsKCgkJd2hpbGUgKGluZHggPCAobmV4dF9hZGQtYWRkMCkvc3RlcCkgewoJCQlpZiAob3B0QmlucyAmJiAoYnVmW2luZHhdIHx8IG9wdEFsbCkpIHsKCQkJCWlmICghaGVhZGVyX3ByaW50ZWQpIHsKCQkJCQlwcmludGYgKCIlczpcbiIsIGZuX25hbWUpOwoJCQkJCWhlYWRlcl9wcmludGVkID0gMTsKCQkJCX0KCQkJCXByaW50ZiAoIlx0JWxseFx0JXVcbiIsIChpbmR4IC0gMSkqc3RlcCArIGFkZDAsIGJ1ZltpbmR4XSk7CgkJCX0KCQkJdGhpcyArPSBidWZbaW5keCsrXTsKCQl9CgkJdG90YWwgKz0gdGhpczsKCgkJaWYgKG9wdEJpbnMpIHsKCQkJaWYgKG9wdFZlcmJvc2UgfHwgdGhpcyA+IDApCgkJCQlwcmludGYgKCIgIHRvdGFsXHRcdFx0XHQldVxuIiwgdGhpcyk7CgkJfSBlbHNlIGlmICgodGhpcyB8fCBvcHRBbGwpICYmCgkJCSAgIChmbl9sZW4gPSBuZXh0X2FkZC1mbl9hZGQpICE9IDApIHsKCQkJaWYgKG9wdFZlcmJvc2UpCgkJCQlwcmludGYoIiUwMTZsbHggJS00MHMgJTZpICU4LjRmXG4iLCBmbl9hZGQsCgkJCQkgICAgICAgZm5fbmFtZSx0aGlzLHRoaXMvKGRvdWJsZSlmbl9sZW4pOwoJCQllbHNlCgkJCQlwcmludGYoIiU2aSAlLTQwcyAlOC40ZlxuIiwKCQkJCSAgICAgICB0aGlzLGZuX25hbWUsdGhpcy8oZG91YmxlKWZuX2xlbik7CgkJCWlmIChvcHRTdWIpIHsKCQkJCXVuc2lnbmVkIGxvbmcgbG9uZyBzY2FuOwoKCQkJCWZvciAoc2NhbiA9IChmbl9hZGQtYWRkMCkvc3RlcCArIDE7CgkJCQkgICAgIHNjYW4gPCAobmV4dF9hZGQtYWRkMCkvc3RlcDsgc2NhbisrKSB7CgkJCQkJdW5zaWduZWQgbG9uZyBsb25nIGFkZHI7CgoJCQkJCWFkZHIgPSAoc2NhbiAtIDEpKnN0ZXAgKyBhZGQwOwoJCQkJCXByaW50ZigiXHQlI2xseFx0JXMrJSNsbHhcdCV1XG4iLAoJCQkJCSAgICAgICBhZGRyLCBmbl9uYW1lLCBhZGRyIC0gZm5fYWRkLAoJCQkJCSAgICAgICBidWZbc2Nhbl0pOwoJCQkJfQoJCQl9CgkJfQoKCQlmbl9hZGQgPSBuZXh0X2FkZDsKCQlzdHJjcHkoZm5fbmFtZSxuZXh0X25hbWUpOwoKCQltYXBsaW5lbm8rKzsKCX0KCgkvKiBjbG9jayB0aWNrcywgb3V0IG9mIGtlcm5lbCB0ZXh0IC0gcHJvYmFibHkgbW9kdWxlcyAqLwoJcHJpbnRmKCIlNmkgJXNcbiIsIGJ1ZltsZW4vc2l6ZW9mKCpidWYpLTFdLCAiKnVua25vd24qIik7CgoJLyogdHJhaWxlciAqLwoJaWYgKG9wdFZlcmJvc2UpCgkJcHJpbnRmKCIlMDE2eCAlLTQwcyAlNmkgJTguNGZcbiIsCgkJICAgICAgIDAsInRvdGFsIix0b3RhbCx0b3RhbC8oZG91YmxlKShmbl9hZGQtYWRkMCkpOwoJZWxzZQoJCXByaW50ZigiJTZpICUtNDBzICU4LjRmXG4iLAoJCSAgICAgICB0b3RhbCwidG90YWwiLHRvdGFsLyhkb3VibGUpKGZuX2FkZC1hZGQwKSk7CgoJZmNsb3NlKG1hcCk7CglmcmVlKGJ1Zik7CgoJcmV0dXJuIEVYSVRfU1VDQ0VTUzsKfQo=