LyoKICogV0lORUQzRCBkcmF3IGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMjAwMi0yMDA0IEphc29uIEVkbWVhZGVzCiAqIENvcHlyaWdodCAyMDAyLTIwMDQgUmFwaGFlbCBKdW5xdWVpcmEKICogQ29weXJpZ2h0IDIwMDQgQ2hyaXN0aWFuIENvc3RhCiAqIENvcHlyaWdodCAyMDA1IE9saXZlciBTdGllYmVyCiAqIENvcHlyaWdodCAyMDA2IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IDIwMDcgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9kcmF3KTsKI2RlZmluZSBHTElORk9fTE9DQVRJT04gVGhpcy0+YWRhcHRlci0+Z2xfaW5mbwoKI2luY2x1ZGUgPHN0ZGlvLmg+CgojaWYgMCAvKiBUT0RPICovCmV4dGVybiBJV2luZUQzRFZlcnRleFNoYWRlckltcGwqICAgICAgICAgICAgVmVydGV4U2hhZGVyc1s2NF07CmV4dGVybiBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uSW1wbCogICAgICAgVmVydGV4U2hhZGVyRGVjbGFyYXRpb25zWzY0XTsKZXh0ZXJuIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKiAgICAgICAgICAgICBQaXhlbFNoYWRlcnNbNjRdOwoKI3VuZGVmIEdMX1ZFUlNJT05fMV80IC8qIFRvIGJlIGZpeGVkLCBjYXVzZWQgYnkgbWVzYSBoZWFkZXJzICovCiNlbmRpZgoKLyogSXNzdWVzIHRoZSBnbEJlZ2luIGNhbGwgZm9yIGdsIGdpdmVuIHRoZSBwcmltaXRpdmUgdHlwZSBhbmQgY291bnQgKi8Kc3RhdGljIERXT1JEIHByaW1pdGl2ZVRvR2woV0lORUQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICBEV09SRCAgICAgICAgICAgIE51bVByaW1pdGl2ZXMsCiAgICAgICAgICAgICAgICAgICAgR0xlbnVtICAgICAgICAgICpwcmltVHlwZSkKewogICAgRFdPUkQgICBOdW1WZXJ0ZXhlcyA9IE51bVByaW1pdGl2ZXM7CgogICAgc3dpdGNoIChQcmltaXRpdmVUeXBlKSB7CiAgICBjYXNlIFdJTkVEM0RQVF9QT0lOVExJU1Q6CiAgICAgICAgVFJBQ0UoIlBPSU5UU1xuIik7CiAgICAgICAgKnByaW1UeXBlICAgPSBHTF9QT0lOVFM7CiAgICAgICAgTnVtVmVydGV4ZXMgPSBOdW1QcmltaXRpdmVzOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFBUX0xJTkVMSVNUOgogICAgICAgIFRSQUNFKCJMSU5FU1xuIik7CiAgICAgICAgKnByaW1UeXBlICAgPSBHTF9MSU5FUzsKICAgICAgICBOdW1WZXJ0ZXhlcyA9IE51bVByaW1pdGl2ZXMgKiAyOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFBUX0xJTkVTVFJJUDoKICAgICAgICBUUkFDRSgiTElORV9TVFJJUFxuIik7CiAgICAgICAgKnByaW1UeXBlICAgPSBHTF9MSU5FX1NUUklQOwogICAgICAgIE51bVZlcnRleGVzID0gTnVtUHJpbWl0aXZlcyArIDE7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUFRfVFJJQU5HTEVMSVNUOgogICAgICAgIFRSQUNFKCJUUklBTkdMRVNcbiIpOwogICAgICAgICpwcmltVHlwZSAgID0gR0xfVFJJQU5HTEVTOwogICAgICAgIE51bVZlcnRleGVzID0gTnVtUHJpbWl0aXZlcyAqIDM7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUFRfVFJJQU5HTEVTVFJJUDoKICAgICAgICBUUkFDRSgiVFJJQU5HTEVfU1RSSVBcbiIpOwogICAgICAgICpwcmltVHlwZSAgID0gR0xfVFJJQU5HTEVfU1RSSVA7CiAgICAgICAgTnVtVmVydGV4ZXMgPSBOdW1QcmltaXRpdmVzICsgMjsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RQVF9UUklBTkdMRUZBTjoKICAgICAgICBUUkFDRSgiVFJJQU5HTEVfRkFOXG4iKTsKICAgICAgICAqcHJpbVR5cGUgICA9IEdMX1RSSUFOR0xFX0ZBTjsKICAgICAgICBOdW1WZXJ0ZXhlcyA9IE51bVByaW1pdGl2ZXMgKyAyOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIlVuaGFuZGxlZCBwcmltaXRpdmVcbiIpOwogICAgICAgICpwcmltVHlwZSAgICA9IEdMX1BPSU5UUzsKICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBOdW1WZXJ0ZXhlczsKfQoKc3RhdGljIEJPT0wgZml4ZWRfZ2V0X2lucHV0KAogICAgQllURSB1c2FnZSwgQllURSB1c2FnZV9pZHgsCiAgICB1bnNpZ25lZCBpbnQqIHJlZ251bSkgewoKICAgICpyZWdudW0gPSAtMTsKCiAgICAvKiBUaG9zZSBwb3NpdGlvbnMgbXVzdCBoYXZlIHRoZSBvcmRlciBpbiB0aGUKICAgICAqIG5hbWVkIHBhcnQgb2YgdGhlIHN0cmlkZWQgZGF0YSAqLwoKICAgIGlmICgodXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9QT1NJVElPTiB8fCB1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX1BPU0lUSU9OVCkgJiYgdXNhZ2VfaWR4ID09IDApCiAgICAgICAgKnJlZ251bSA9IDA7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX0JMRU5EV0VJR0hUICYmIHVzYWdlX2lkeCA9PSAwKQogICAgICAgICpyZWdudW0gPSAxOwogICAgZWxzZSBpZiAodXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9CTEVORElORElDRVMgJiYgdXNhZ2VfaWR4ID09IDApCiAgICAgICAgKnJlZ251bSA9IDI7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX05PUk1BTCAmJiB1c2FnZV9pZHggPT0gMCkKICAgICAgICAqcmVnbnVtID0gMzsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfUFNJWkUgJiYgdXNhZ2VfaWR4ID09IDApCiAgICAgICAgKnJlZ251bSA9IDQ7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX0NPTE9SICYmIHVzYWdlX2lkeCA9PSAwKQogICAgICAgICpyZWdudW0gPSA1OwogICAgZWxzZSBpZiAodXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9DT0xPUiAmJiB1c2FnZV9pZHggPT0gMSkKICAgICAgICAqcmVnbnVtID0gNjsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfVEVYQ09PUkQgJiYgdXNhZ2VfaWR4IDwgV0lORUQzRERQX01BWFRFWENPT1JEKQogICAgICAgICpyZWdudW0gPSA3ICsgdXNhZ2VfaWR4OwogICAgZWxzZSBpZiAoKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfUE9TSVRJT04gfHwgdXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9QT1NJVElPTlQpICYmIHVzYWdlX2lkeCA9PSAxKQogICAgICAgICpyZWdudW0gPSA3ICsgV0lORUQzRERQX01BWFRFWENPT1JEOwogICAgZWxzZSBpZiAodXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9OT1JNQUwgJiYgdXNhZ2VfaWR4ID09IDEpCiAgICAgICAgKnJlZ251bSA9IDggKyBXSU5FRDNERFBfTUFYVEVYQ09PUkQ7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX1RBTkdFTlQgJiYgdXNhZ2VfaWR4ID09IDApCiAgICAgICAgKnJlZ251bSA9IDkgKyBXSU5FRDNERFBfTUFYVEVYQ09PUkQ7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX0JJTk9STUFMICYmIHVzYWdlX2lkeCA9PSAwKQogICAgICAgICpyZWdudW0gPSAxMCArIFdJTkVEM0REUF9NQVhURVhDT09SRDsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfVEVTU0ZBQ1RPUiAmJiB1c2FnZV9pZHggPT0gMCkKICAgICAgICAqcmVnbnVtID0gMTEgKyBXSU5FRDNERFBfTUFYVEVYQ09PUkQ7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX0ZPRyAmJiB1c2FnZV9pZHggPT0gMCkKICAgICAgICAqcmVnbnVtID0gMTIgKyBXSU5FRDNERFBfTUFYVEVYQ09PUkQ7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX0RFUFRIICYmIHVzYWdlX2lkeCA9PSAwKQogICAgICAgICpyZWdudW0gPSAxMyArIFdJTkVEM0REUF9NQVhURVhDT09SRDsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfU0FNUExFICYmIHVzYWdlX2lkeCA9PSAwKQogICAgICAgICpyZWdudW0gPSAxNCArIFdJTkVEM0REUF9NQVhURVhDT09SRDsKCiAgICBpZiAoKnJlZ251bSA9PSAtMSkgewogICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBpbnB1dCBzdHJlYW0gW3VzYWdlPSVzLCB1c2FnZV9pZHg9JXVdXG4iLAogICAgICAgICAgICBkZWJ1Z19kM2RkZWNsdXNhZ2UodXNhZ2UpLCB1c2FnZV9pZHgpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9Cgp2b2lkIHByaW1pdGl2ZURlY2xhcmF0aW9uQ29udmVydFRvU3RyaWRlZERhdGEoCiAgICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgIEJPT0wgdXNlVmVydGV4U2hhZGVyRnVuY3Rpb24sCiAgICAgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKnN0cmlkZWQsCiAgICAgQk9PTCAqZml4dXApIHsKCiAgICAgLyogV2UgbmVlZCB0byBkZWFsIHdpdGggZnJlcXVlbmN5IGRhdGEhKi8KCiAgICBCWVRFICAqZGF0YSAgICA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uSW1wbCogdmVydGV4RGVjbGFyYXRpb24gPSAoSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbkltcGwgKilUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsOwogICAgaW50IGk7CiAgICBXSU5FRDNEVkVSVEVYRUxFTUVOVCAqZWxlbWVudDsKICAgIERXT1JEIHN0cmlkZTsKICAgIGludCByZWc7CiAgICBEV09SRCBudW1QcmVsb2FkU3RyZWFtcyA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPyAwIDogdmVydGV4RGVjbGFyYXRpb24tPm51bV9zdHJlYW1zOwogICAgRFdPUkQgKnN0cmVhbXMgPSB2ZXJ0ZXhEZWNsYXJhdGlvbi0+c3RyZWFtczsKCiAgICAvKiBDaGVjayBmb3IgdHJhbnNmb3JtZWQgdmVydGljZXMsIGRpc2FibGUgdmVydGV4IHNoYWRlciBpZiBwcmVzZW50ICovCiAgICBzdHJpZGVkLT51LnMucG9zaXRpb25fdHJhbnNmb3JtZWQgPSB2ZXJ0ZXhEZWNsYXJhdGlvbi0+cG9zaXRpb25fdHJhbnNmb3JtZWQ7CiAgICBpZih2ZXJ0ZXhEZWNsYXJhdGlvbi0+cG9zaXRpb25fdHJhbnNmb3JtZWQpIHsKICAgICAgICB1c2VWZXJ0ZXhTaGFkZXJGdW5jdGlvbiA9IEZBTFNFOwogICAgfQoKICAgIC8qIFRyYW5zbGF0ZSB0aGUgZGVjbGFyYXRpb24gaW50byBzdHJpZGVkIGRhdGEgKi8KICAgIGZvciAoaSA9IDAgOyBpIDwgdmVydGV4RGVjbGFyYXRpb24tPmRlY2xhcmF0aW9uV051bUVsZW1lbnRzIC0gMTsgKytpKSB7CiAgICAgICAgR0xpbnQgc3RyZWFtVkJPID0gMDsKICAgICAgICBCT09MIHN0cmlkZV91c2VkOwogICAgICAgIHVuc2lnbmVkIGludCBpZHg7CgogICAgICAgIGVsZW1lbnQgPSB2ZXJ0ZXhEZWNsYXJhdGlvbi0+cERlY2xhcmF0aW9uV2luZSArIGk7CiAgICAgICAgVFJBQ0UoIiVwIEVsZW1lbnQgJXAgKCVkIG9mICVkKVxuIiwgdmVydGV4RGVjbGFyYXRpb24tPnBEZWNsYXJhdGlvbldpbmUsCiAgICAgICAgICAgIGVsZW1lbnQsICBpICsgMSwgdmVydGV4RGVjbGFyYXRpb24tPmRlY2xhcmF0aW9uV051bUVsZW1lbnRzIC0gMSk7CgogICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbZWxlbWVudC0+U3RyZWFtXSA9PSBOVUxMKQogICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgc3RyaWRlICA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVtlbGVtZW50LT5TdHJlYW1dOwogICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQKSB7CiAgICAgICAgICAgIFRSQUNFKCJTdHJlYW0gaXMgdXAgJWQsICVwXG4iLCBlbGVtZW50LT5TdHJlYW0sIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtlbGVtZW50LT5TdHJlYW1dKTsKICAgICAgICAgICAgc3RyZWFtVkJPID0gMDsKICAgICAgICAgICAgZGF0YSAgICA9IChCWVRFICopVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW2VsZW1lbnQtPlN0cmVhbV07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIlN0cmVhbSBpc24ndCB1cCAlZCwgJXBcbiIsIGVsZW1lbnQtPlN0cmVhbSwgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW2VsZW1lbnQtPlN0cmVhbV0pOwogICAgICAgICAgICBkYXRhICAgID0gSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsX0dldE1lbW9yeShUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbZWxlbWVudC0+U3RyZWFtXSwgMCwgJnN0cmVhbVZCTyk7CgogICAgICAgICAgICAvKiBDYW4ndCB1c2UgdmJvJ3MgaWYgdGhlIGJhc2UgdmVydGV4IGluZGV4IGlzIG5lZ2F0aXZlLiBPcGVuR0wgZG9lc24ndCBhY2NlcHQgbmVnYXRpdmUgb2Zmc2V0cwogICAgICAgICAgICAgKiAob3IgcmF0aGVyIG9mZnNldHMgYmlnZ2VyIHRoYW4gdGhlIHZibywgYmVjYXVzZSB0aGUgcG9pbnRlciBpcyB1bnNpZ25lZCksIHNvIHVzZSBzeXN0ZW0gbWVtb3J5CiAgICAgICAgICAgICAqIHNvdXJjZXMuIEluIG1vc3Qgc2FuZSBjYXNlcyB0aGUgcG9pbnRlciAtIG9mZnNldCB3aWxsIHN0aWxsIGJlID4gMCwgb3RoZXJ3aXNlIGl0IHdpbGwgd3JhcAogICAgICAgICAgICAgKiBhcm91bmQgdG8gc29tZSBiaWcgdmFsdWUuIEhvcGUgdGhhdCB3aXRoIHRoZSBpbmRpY2VzLCB0aGUgZHJpdmVyIHdyYXBzIGl0IGJhY2sgaW50ZXJuYWxseS4gSWYKICAgICAgICAgICAgICogbm90LCBkcmF3U3RyaWRlZFNsb3cgaXMgbmVlZGVkLCBpbmNsdWRpbmcgYSB2ZXJ0ZXggYnVmZmVyIHBhdGguCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4IDwgMCkgewogICAgICAgICAgICAgICAgV0FSTigibG9hZEJhc2VWZXJ0ZXhJbmRleCBpcyA8IDAgKCVkKSwgbm90IHVzaW5nIHZib3NcbiIsIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXgpOwogICAgICAgICAgICAgICAgc3RyZWFtVkJPID0gMDsKICAgICAgICAgICAgICAgIGRhdGEgPSAoKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbZWxlbWVudC0+U3RyZWFtXSktPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgICAgIGlmKChVSU5UX1BUUilkYXRhIDwgLVRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggKiBzdHJpZGUpIHsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiU3lzdGVtIG1lbW9yeSB2ZXJ0ZXggZGF0YSBsb2FkIG9mZnNldCBpcyBuZWdhdGl2ZSFcbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihmaXh1cCkgewogICAgICAgICAgICAgICAgaWYoIHN0cmVhbVZCTyAhPSAwKSAqZml4dXAgPSBUUlVFOwogICAgICAgICAgICAgICAgZWxzZSBpZigqZml4dXAgJiYgIXVzZVZlcnRleFNoYWRlckZ1bmN0aW9uICYmCiAgICAgICAgICAgICAgICAgICAgICAgKGVsZW1lbnQtPlVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfQ09MT1IgfHwKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC0+VXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9QT1NJVElPTlQpKSB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBtYXkgYmUgYmFkIHdpdGggdGhlIGZpeGVkIGZ1bmN0aW9uIHBpcGVsaW5lICovCiAgICAgICAgICAgICAgICAgICAgRklYTUUoIk1pc3NpbmcgdmJvIHN0cmVhbXMgd2l0aCB1bmZpeGVkIGNvbG9ycyBvciB0cmFuc2Zvcm1lZCBwb3NpdGlvbiwgZXhwZWN0IHByb2JsZW1zXG4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBkYXRhICs9IGVsZW1lbnQtPk9mZnNldDsKICAgICAgICByZWcgPSBlbGVtZW50LT5SZWc7CgogICAgICAgIFRSQUNFKCJPZmZzZXQgJWQgU3RyZWFtICVkIFVzYWdlSW5kZXggJWRcbiIsIGVsZW1lbnQtPk9mZnNldCwgZWxlbWVudC0+U3RyZWFtLCBlbGVtZW50LT5Vc2FnZUluZGV4KTsKCiAgICAgICAgaWYgKHVzZVZlcnRleFNoYWRlckZ1bmN0aW9uKQogICAgICAgICAgICBzdHJpZGVfdXNlZCA9IHZzaGFkZXJfZ2V0X2lucHV0KFRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlciwKICAgICAgICAgICAgICAgIGVsZW1lbnQtPlVzYWdlLCBlbGVtZW50LT5Vc2FnZUluZGV4LCAmaWR4KTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHN0cmlkZV91c2VkID0gZml4ZWRfZ2V0X2lucHV0KGVsZW1lbnQtPlVzYWdlLCBlbGVtZW50LT5Vc2FnZUluZGV4LCAmaWR4KTsKCiAgICAgICAgaWYgKHN0cmlkZV91c2VkKSB7CiAgICAgICAgICAgIFRSQUNFKCJMb2FkZWQgJXMgYXJyYXkgJXUgW3VzYWdlPSVzLCB1c2FnZV9pZHg9JXUsICIKICAgICAgICAgICAgICAgICAgICAic3RyZWFtPSV1LCBvZmZzZXQ9JXUsIHN0cmlkZT0ldSwgdHlwZT0lcywgVkJPPSV1XVxuIiwKICAgICAgICAgICAgICAgICAgICB1c2VWZXJ0ZXhTaGFkZXJGdW5jdGlvbj8gInNoYWRlciI6ICJmaXhlZCBmdW5jdGlvbiIsIGlkeCwKICAgICAgICAgICAgICAgICAgICBkZWJ1Z19kM2RkZWNsdXNhZ2UoZWxlbWVudC0+VXNhZ2UpLCBlbGVtZW50LT5Vc2FnZUluZGV4LAogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQtPlN0cmVhbSwgZWxlbWVudC0+T2Zmc2V0LCBzdHJpZGUsIGRlYnVnX2QzZGRlY2x0eXBlKGVsZW1lbnQtPlR5cGUpLCBzdHJlYW1WQk8pOwoKICAgICAgICAgICAgc3RyaWRlZC0+dS5pbnB1dFtpZHhdLmxwRGF0YSA9IGRhdGE7CiAgICAgICAgICAgIHN0cmlkZWQtPnUuaW5wdXRbaWR4XS5kd1R5cGUgPSBlbGVtZW50LT5UeXBlOwogICAgICAgICAgICBzdHJpZGVkLT51LmlucHV0W2lkeF0uZHdTdHJpZGUgPSBzdHJpZGU7CiAgICAgICAgICAgIHN0cmlkZWQtPnUuaW5wdXRbaWR4XS5WQk8gPSBzdHJlYW1WQk87CiAgICAgICAgICAgIHN0cmlkZWQtPnUuaW5wdXRbaWR4XS5zdHJlYW1ObyA9IGVsZW1lbnQtPlN0cmVhbTsKICAgICAgICB9CiAgICB9CiAgICAvKiBOb3cgY2FsbCBQcmVMb2FkIG9uIGFsbCB0aGUgdmVydGV4IGJ1ZmZlcnMuIEluIHRoZSB2ZXJ5IHJhcmUgY2FzZQogICAgICogdGhhdCB0aGUgYnVmZmVycyBzdG9wcHMgY29udmVydGluZyBQcmVMb2FkIHdpbGwgZGlydGlmeSB0aGUgVkRFQ0wgYWdhaW4uCiAgICAgKiBUaGUgdmVydGV4IGJ1ZmZlciBjYW4gbm93IHVzZSB0aGUgc3RyaWRlZCBzdHJ1Y3R1cmUgaW4gdGhlIGRldmljZSBpbnN0ZWFkIG9mIGZpbmRpbmcgaXRzCiAgICAgKiBvd24gYWdhaW4uCiAgICAgKgogICAgICogTlVMTCBzdHJlYW1zIHdvbid0IGJlIHJlY29yZGVkIGluIHRoZSBhcnJheSwgVVAgc3RyZWFtcyB3b24ndCBiZSBlaXRoZXIuIEEgc3RyZWFtIGlzIG9ubHkKICAgICAqIG9uY2UgaW4gdGhlcmUuCiAgICAgKi8KICAgIGZvcihpPTA7IGkgPCBudW1QcmVsb2FkU3RyZWFtczsgaSsrKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKnZiID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmVhbXNbaV1dOwogICAgICAgIGlmKHZiKSB7CiAgICAgICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX1ByZUxvYWQodmIpOwogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIHZvaWQgZHJhd1N0cmlkZWRGYXN0KElXaW5lRDNERGV2aWNlICppZmFjZSxVSU5UIG51bWJlck9mVmVydGljZXMsIEdMZW51bSBnbFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmlkeERhdGEsIHNob3J0IGlkeFNpemUsIFVMT05HIG1pbkluZGV4LCBVTE9ORyBzdGFydElkeCwgVUxPTkcgc3RhcnRWZXJ0ZXgpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpZiAoaWR4U2l6ZSAhPSAwIC8qIFRoaXMgY3Jhc2hlcyBzb21ldGltZXMhKi8pIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IGdsRWxlbWVudHMoJXgsICVkLCAlZCwgLi4uKVxuIiwgVGhpcywgZ2xQcmltaXRpdmVUeXBlLCBudW1iZXJPZlZlcnRpY2VzLCBtaW5JbmRleCk7CiAgICAgICAgaWR4RGF0YSA9IGlkeERhdGEgPT0gKHZvaWQgKiktMSA/IE5VTEwgOiBpZHhEYXRhOwojaWYgMQogICAgICAgIGdsRHJhd0VsZW1lbnRzKGdsUHJpbWl0aXZlVHlwZSwgbnVtYmVyT2ZWZXJ0aWNlcywgaWR4U2l6ZSA9PSAyID8gR0xfVU5TSUdORURfU0hPUlQgOiBHTF9VTlNJR05FRF9JTlQsCiAgICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopaWR4RGF0YSsoaWR4U2l6ZSAqIHN0YXJ0SWR4KSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0VsZW1lbnRzIik7CiNlbHNlIC8qIHVzaW5nIGRyYXdSYW5nZUVsZW1lbnRzIG1heSBiZSBmYXN0ZXIgKi8KCiAgICAgICAgZ2xEcmF3UmFuZ2VFbGVtZW50cyhnbFByaW1pdGl2ZVR5cGUsIG1pbkluZGV4LCBtaW5JbmRleCArIG51bWJlck9mVmVydGljZXMgLSAxLCBudW1iZXJPZlZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgaWR4U2l6ZSA9PSAyID8gR0xfVU5TSUdORURfU0hPUlQgOiBHTF9VTlNJR05FRF9JTlQsCiAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKWlkeERhdGErKGlkeFNpemUgKiBzdGFydElkeCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdSYW5nZUVsZW1lbnRzIik7CiNlbmRpZgoKICAgIH0gZWxzZSB7CgogICAgICAgIC8qIE5vdGUgZmlyc3QgaXMgbm93IHplcm8gYXMgd2Ugc2h1ZmZsZWQgYWxvbmcgZWFybGllciAqLwogICAgICAgIFRSQUNFKCIoJXApIDogZ2xEcmF3QXJyYXlzKCV4LCAwLCAlZClcbiIsIFRoaXMsIGdsUHJpbWl0aXZlVHlwZSwgbnVtYmVyT2ZWZXJ0aWNlcyk7CiAgICAgICAgZ2xEcmF3QXJyYXlzKGdsUHJpbWl0aXZlVHlwZSwgc3RhcnRWZXJ0ZXgsIG51bWJlck9mVmVydGljZXMpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdBcnJheXMiKTsKCiAgICB9CgogICAgcmV0dXJuOwp9CgovKgogKiBBY3R1YWxseSBkcmF3IHVzaW5nIHRoZSBzdXBwbGllZCBpbmZvcm1hdGlvbi4KICogU2xvd2VyIEdMIHZlcnNpb24gd2hpY2ggZXh0cmFjdHMgaW5mbyBhYm91dCBlYWNoIHZlcnRleCBpbiB0dXJuCiAqLwoKc3RhdGljIHZvaWQgZHJhd1N0cmlkZWRTbG93KElXaW5lRDNERGV2aWNlICppZmFjZSwgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKnNkLAogICAgICAgICAgICAgICAgICAgICBVSU5UIE51bVZlcnRleGVzLCBHTGVudW0gZ2xQcmltVHlwZSwKICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqaWR4RGF0YSwgc2hvcnQgaWR4U2l6ZSwgVUxPTkcgbWluSW5kZXgsIFVMT05HIHN0YXJ0SWR4LCBVTE9ORyBzdGFydFZlcnRleCkgewoKICAgIHVuc2lnbmVkIGludCAgICAgICAgICAgICAgIHRleHR1cmVObyAgICA9IDA7CiAgICBjb25zdCBXT1JEICAgICAgICAgICAgICAgICpwSWR4QnVmUyAgICAgPSBOVUxMOwogICAgY29uc3QgRFdPUkQgICAgICAgICAgICAgICAqcElkeEJ1ZkwgICAgID0gTlVMTDsKICAgIExPTkcgICAgICAgICAgICAgICAgICAgICAgIHZ4X2luZGV4OwogICAgZmxvYXQgeCAgPSAwLjBmLCB5ICA9IDAuMGYsIHogPSAwLjBmOyAgLyogeCx5LHogY29vcmRpbmF0ZXMgICAgICAgICAgKi8KICAgIGZsb2F0IHJodyA9IDAuMGY7ICAgICAgICAgICAgICAgICAgICAgIC8qIHJodyAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBEV09SRCBkaWZmdXNlQ29sb3IgPSAweEZGRkZGRkZGOyAgICAgICAvKiBEaWZmdXNlIENvbG9yICAgICAgICAgICAgICAqLwogICAgRFdPUkQgc3BlY3VsYXJDb2xvciA9IDA7ICAgICAgICAgICAgICAgLyogU3BlY3VsYXIgQ29sb3IgICAgICAgICAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVJTlQgKnN0cmVhbU9mZnNldCA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbU9mZnNldDsKICAgIGxvbmcgICAgICAgICAgICAgICAgICAgICAgU2tpcG5TdHJpZGVzID0gc3RhcnRWZXJ0ZXggKyBUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4OwogICAgQk9PTCAgICAgICAgICAgICAgICAgICAgICBwaXhlbFNoYWRlciA9IHVzZV9wcyhUaGlzKTsKCiAgICBCWVRFICp0ZXhDb29yZHNbV0lORUQzRERQX01BWFRFWENPT1JEXTsKICAgIEJZVEUgKmRpZmZ1c2UgPSBOVUxMLCAqc3BlY3VsYXIgPSBOVUxMLCAqbm9ybWFsID0gTlVMTCwgKnBvc2l0aW9uID0gTlVMTDsKCiAgICBUUkFDRSgiVXNpbmcgc2xvdyB2ZXJ0ZXggYXJyYXkgY29kZVxuIik7CgogICAgLyogVmFyaWFibGUgSW5pdGlhbGl6YXRpb24gKi8KICAgIGlmIChpZHhTaXplICE9IDApIHsKICAgICAgICAvKiBJbW1lZGlhdGUgbW9kZSBkcmF3aW5nIGNhbid0IG1ha2UgdXNlIG9mIGluZGljZXMgaW4gYSB2Ym8gLSBnZXQgdGhlIGRhdGEgZnJvbSB0aGUgaW5kZXggYnVmZmVyLgogICAgICAgICAqIElmIHRoZSBpbmRleCBidWZmZXIgaGFzIG5vIHZibyhub3Qgc3VwcG9ydGVkIG9yIG90aGVyIHJlYXNvbiksIG9yIHdpdGggdXNlciBwb2ludGVyIGRyYXdpbmcKICAgICAgICAgKiBpZHhEYXRhIHdpbGwgYmUgIT0gTlVMTAogICAgICAgICAqLwogICAgICAgIGlmKGlkeERhdGEgPT0gTlVMTCkgewogICAgICAgICAgICBpZHhEYXRhID0gKChJV2luZUQzREluZGV4QnVmZmVySW1wbCAqKSBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhKS0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIH0KCiAgICAgICAgaWYgKGlkeFNpemUgPT0gMikgcElkeEJ1ZlMgPSAoY29uc3QgV09SRCAqKSBpZHhEYXRhOwogICAgICAgIGVsc2UgcElkeEJ1ZkwgPSAoY29uc3QgRFdPUkQgKikgaWR4RGF0YTsKICAgIH0KCiAgICAvKiBBZGRpbmcgdGhlIHN0cmVhbSBvZmZzZXQgb25jZSBpcyBjaGVhcGVyIHRoYW4gZG9pbmcgaXQgZXZlcnkgaXRlcmF0aW9uLiBEbyBub3QgbW9kaWZ5IHRoZSBzdHJpZGVkIGRhdGEsIGl0IGlzIGEgcG9pbnRlcgogICAgICogdG8gdGhlIHN0cmlkZWQgRGF0YSBpbiB0aGUgZGV2aWNlIGFuZCBtaWdodCBiZSBuZWVkZWQgaW50YWN0IG9uIHRoZSBuZXh0IGRyYXcKICAgICAqLwogICAgZm9yICh0ZXh0dXJlTm8gPSAwOyB0ZXh0dXJlTm8gPCBHTF9MSU1JVFModGV4dHVyZV9zdGFnZXMpOyArK3RleHR1cmVObykgewogICAgICAgIGlmKHNkLT51LnMudGV4Q29vcmRzW3RleHR1cmVOb10ubHBEYXRhKSB7CiAgICAgICAgICAgIHRleENvb3Jkc1t0ZXh0dXJlTm9dID0gc2QtPnUucy50ZXhDb29yZHNbdGV4dHVyZU5vXS5scERhdGEgKyBzdHJlYW1PZmZzZXRbc2QtPnUucy50ZXhDb29yZHNbdGV4dHVyZU5vXS5zdHJlYW1Ob107CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGV4Q29vcmRzW3RleHR1cmVOb10gPSBOVUxMOwogICAgICAgIH0KICAgIH0KICAgIGlmKHNkLT51LnMuZGlmZnVzZS5scERhdGEpIHsKICAgICAgICBkaWZmdXNlID0gc2QtPnUucy5kaWZmdXNlLmxwRGF0YSArIHN0cmVhbU9mZnNldFtzZC0+dS5zLmRpZmZ1c2Uuc3RyZWFtTm9dOwogICAgfQogICAgaWYoc2QtPnUucy5zcGVjdWxhci5scERhdGEpIHsKICAgICAgICBzcGVjdWxhciA9IHNkLT51LnMuc3BlY3VsYXIubHBEYXRhICsgc3RyZWFtT2Zmc2V0W3NkLT51LnMuc3BlY3VsYXIuc3RyZWFtTm9dOwogICAgfQogICAgaWYoc2QtPnUucy5ub3JtYWwubHBEYXRhKSB7CiAgICAgICAgbm9ybWFsID0gc2QtPnUucy5ub3JtYWwubHBEYXRhICsgc3RyZWFtT2Zmc2V0W3NkLT51LnMubm9ybWFsLnN0cmVhbU5vXTsKICAgIH0KICAgIGlmKHNkLT51LnMucG9zaXRpb24ubHBEYXRhKSB7CiAgICAgICAgcG9zaXRpb24gPSBzZC0+dS5zLnBvc2l0aW9uLmxwRGF0YSArIHN0cmVhbU9mZnNldFtzZC0+dS5zLnBvc2l0aW9uLnN0cmVhbU5vXTsKICAgIH0KCiAgICAvKiBTdGFydCBkcmF3aW5nIGluIEdMICovCiAgICBWVFJBQ0UoKCJnbEJlZ2luKCV4KVxuIiwgZ2xQcmltVHlwZSkpOwogICAgZ2xCZWdpbihnbFByaW1UeXBlKTsKCiAgICAvKiBEZWZhdWx0IHNldHRpbmdzIGZvciBkYXRhIHRoYXQgaXMgbm90IHBhc3NlZCAqLwogICAgaWYgKHNkLT51LnMubm9ybWFsLmxwRGF0YSA9PSBOVUxMKSB7CiAgICAgICAgZ2xOb3JtYWwzZigwLCAwLCAwKTsKICAgIH0KICAgIGlmKHNkLT51LnMuZGlmZnVzZS5scERhdGEgPT0gTlVMTCkgewogICAgICAgIGdsQ29sb3I0ZigxLjBmLCAxLjBmLCAxLjBmLCAxLjBmKTsKICAgIH0KICAgIGlmKHNkLT51LnMuc3BlY3VsYXIubHBEYXRhID09IE5VTEwpIHsKICAgICAgICBpZiAoR0xfU1VQUE9SVChFWFRfU0VDT05EQVJZX0NPTE9SKSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsU2Vjb25kYXJ5Q29sb3IzZkVYVCkoMCwgMCwgMCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFdlIHNob3VsZG4ndCBzdGFydCB0aGlzIGZ1bmN0aW9uIGlmIGFueSBWQk8gaXMgaW52b2x2ZWQuIFNob3VsZCBJIHB1dCBhIHNhZmV0eSBjaGVjayBoZXJlPwogICAgICogR3Vlc3MgaXQncyBub3QgbmVjZXNzYXJ5KHdlIGNyYXNoIHRoZW4gYW55d2F5KSBhbmQgd291bGQgb25seSBlYXQgQ1BVIHRpbWUKICAgICAqLwoKICAgIC8qIEZvciBlYWNoIHByaW1pdGl2ZSAqLwogICAgZm9yICh2eF9pbmRleCA9IDA7IHZ4X2luZGV4IDwgTnVtVmVydGV4ZXM7ICsrdnhfaW5kZXgpIHsKCiAgICAgICAgLyogSW5pdGlhbGl6ZSBkaWZmdXNlIGNvbG9yICovCiAgICAgICAgZGlmZnVzZUNvbG9yID0gMHhGRkZGRkZGRjsKCiAgICAgICAgLyogQmxlbmRpbmcgZGF0YSBhbmQgUG9pbnQgc2l6ZXMgYXJlIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBmdW5jdGlvbi4gVGhleSBhcmUgbm90IHN1cHBvcnRlZCBieSB0aGUgZml4ZWQKICAgICAgICAgKiBmdW5jdGlvbiBwaXBlbGluZSBhdCBhbGwuIEEgRml4bWUgZm9yIHRoZW0gaXMgcHJpbnRlZCBhZnRlciBkZWNvZGluZyB0aGUgdmVydGV4IGRlY2xhcmF0aW9uCiAgICAgICAgICovCgogICAgICAgIC8qIEZvciBpbmRleGVkIGRhdGEsIHdlIG5lZWQgdG8gZ28gYSBmZXcgbW9yZSBzdHJpZGVzIGluICovCiAgICAgICAgaWYgKGlkeERhdGEgIT0gTlVMTCkgewoKICAgICAgICAgICAgLyogSW5kZXhlZCBzbyB3b3JrIG91dCB0aGUgbnVtYmVyIG9mIHN0cmlkZXMgdG8gc2tpcCAqLwogICAgICAgICAgICBpZiAoaWR4U2l6ZSA9PSAyKSB7CiAgICAgICAgICAgICAgICBWVFJBQ0UoKCJJZHggZm9yIHZlcnRleCAlZCA9ICVkXG4iLCB2eF9pbmRleCwgcElkeEJ1ZlNbc3RhcnRJZHgrdnhfaW5kZXhdKSk7CiAgICAgICAgICAgICAgICBTa2lwblN0cmlkZXMgPSBwSWR4QnVmU1tzdGFydElkeCArIHZ4X2luZGV4XSArIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXg7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBWVFJBQ0UoKCJJZHggZm9yIHZlcnRleCAlZCA9ICVkXG4iLCB2eF9pbmRleCwgcElkeEJ1Zkxbc3RhcnRJZHgrdnhfaW5kZXhdKSk7CiAgICAgICAgICAgICAgICBTa2lwblN0cmlkZXMgPSBwSWR4QnVmTFtzdGFydElkeCArIHZ4X2luZGV4XSArIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXg7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIFRleHR1cmUgY29vcmRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgIGZvciAodGV4dHVyZU5vID0gMDsgdGV4dHVyZU5vIDwgR0xfTElNSVRTKHRleHR1cmVfc3RhZ2VzKTsgKyt0ZXh0dXJlTm8pIHsKCiAgICAgICAgICAgIGlmICghR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSAmJiB0ZXh0dXJlTm8gPiAwKSB7CiAgICAgICAgICAgICAgICBGSVhNRSgiUHJvZ3JhbSB1c2luZyBtdWx0aXBsZSBjb25jdXJyZW50IHRleHR1cmVzIHdoaWNoIHRoaXMgb3BlbmdsIGltcGxlbWVudGF0aW9uIGRvZXNuJ3Qgc3VwcG9ydFxuIik7CiAgICAgICAgICAgICAgICBjb250aW51ZSA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFF1ZXJ5IHRleCBjb29yZHMgKi8KICAgICAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW3RleHR1cmVOb10gIT0gTlVMTCB8fCBwaXhlbFNoYWRlcikgewoKICAgICAgICAgICAgICAgIGludCAgICBjb29yZElkeCA9IFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVt0ZXh0dXJlTm9dW1dJTkVEM0RUU1NfVEVYQ09PUkRJTkRFWF07CiAgICAgICAgICAgICAgICBpbnQgdGV4dHVyZV9pZHggPSBUaGlzLT50ZXhVbml0TWFwW3RleHR1cmVOb107CiAgICAgICAgICAgICAgICBmbG9hdCAqcHRyVG9Db29yZHMgPSBOVUxMOwogICAgICAgICAgICAgICAgZmxvYXQgIHMgPSAwLjAsIHQgPSAwLjAsIHIgPSAwLjAsIHEgPSAwLjA7CgogICAgICAgICAgICAgICAgaWYgKGNvb3JkSWR4ID4gNykgewogICAgICAgICAgICAgICAgICAgIFZUUkFDRSgoInRleDogJWQgLSBTa2lwIHRleCBjb29yZHMsIGFzIGJlaW5nIHN5c3RlbSBnZW5lcmF0ZWRcbiIsIHRleHR1cmVObykpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb29yZElkeCA8IDApIHsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgidGV4OiAlZCAtIENvb3JkIGluZGV4ICVkIGlzIGxlc3MgdGhhbiB6ZXJvLCBleHBlY3QgYSBjcmFzaC5cbiIsIHRleHR1cmVObywgY29vcmRJZHgpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHB0clRvQ29vcmRzID0gKGZsb2F0ICopKHRleENvb3Jkc1tjb29yZElkeF0gKyAoU2tpcG5TdHJpZGVzICogc2QtPnUucy50ZXhDb29yZHNbY29vcmRJZHhdLmR3U3RyaWRlKSk7CiAgICAgICAgICAgICAgICBpZiAodGV4Q29vcmRzW2Nvb3JkSWR4XSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInRleDogJWQgLSBTa2lwcGluZyB0ZXggY29vcmRzLCBhcyBubyBkYXRhIHN1cHBsaWVkXG4iLCB0ZXh0dXJlTm8pOwogICAgICAgICAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xNdWx0aVRleENvb3JkNGZBUkIoR0xfVEVYVFVSRTBfQVJCICsgdGV4dHVyZV9pZHgsIDAsIDAsIDAsIDEpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBnbFRleENvb3JkNGYoMCwgMCwgMCwgMSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpbnQgY29vcmRzVG9Vc2UgPSBzZC0+dS5zLnRleENvb3Jkc1tjb29yZElkeF0uZHdUeXBlICsgMTsgLyogMCA9PSBXSU5FRDNEREVDTFRZUEVfRkxPQVQxIGV0YyAqLwoKICAgICAgICAgICAgICAgICAgICBpZiAodGV4dHVyZV9pZHggPT0gLTEpIGNvbnRpbnVlOwoKICAgICAgICAgICAgICAgICAgICAvKiBUaGUgY29vcmRzIHRvIHN1cHBseSBkZXBlbmQgY29tcGxldGVseSBvbiB0aGUgZnZmIC8gdmVydGV4IHNoYWRlciAqLwogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY29vcmRzVG9Vc2UpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IHEgPSBwdHJUb0Nvb3Jkc1szXTsgLyogZHJvcCB0aHJvdWdoICovCiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOiByID0gcHRyVG9Db29yZHNbMl07IC8qIGRyb3AgdGhyb3VnaCAqLwogICAgICAgICAgICAgICAgICAgIGNhc2UgMjogdCA9IHB0clRvQ29vcmRzWzFdOyAvKiBkcm9wIHRocm91Z2ggKi8KICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IHMgPSBwdHJUb0Nvb3Jkc1swXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY29vcmRzVG9Vc2UpIHsgICAvKiBTdXBwbHkgdGhlIHByb3ZpZGVkIHRleHR1cmUgY29vcmRzICovCiAgICAgICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9DT1VOVDE6CiAgICAgICAgICAgICAgICAgICAgICAgIFZUUkFDRSgoInRleDolZCwgcz0lZlxuIiwgdGV4dHVyZU5vLCBzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsTXVsdGlUZXhDb29yZDFmQVJCKEdMX1RFWFRVUkUwX0FSQiArIHRleHR1cmVfaWR4LCBzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRleENvb3JkMWYocyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9DT1VOVDI6CiAgICAgICAgICAgICAgICAgICAgICAgIFZUUkFDRSgoInRleDolZCwgcz0lZiwgdD0lZlxuIiwgdGV4dHVyZU5vLCBzLCB0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsTXVsdGlUZXhDb29yZDJmQVJCKEdMX1RFWFRVUkUwX0FSQiArIHRleHR1cmVfaWR4LCBzLCB0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRleENvb3JkMmYocywgdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9DT1VOVDM6CiAgICAgICAgICAgICAgICAgICAgICAgIFZUUkFDRSgoInRleDolZCwgcz0lZiwgdD0lZiwgcj0lZlxuIiwgdGV4dHVyZU5vLCBzLCB0LCByKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsTXVsdGlUZXhDb29yZDNmQVJCKEdMX1RFWFRVUkUwX0FSQiArIHRleHR1cmVfaWR4LCBzLCB0LCByKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRleENvb3JkM2YocywgdCwgcik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9DT1VOVDQ6CiAgICAgICAgICAgICAgICAgICAgICAgIFZUUkFDRSgoInRleDolZCwgcz0lZiwgdD0lZiwgcj0lZiwgcT0lZlxuIiwgdGV4dHVyZU5vLCBzLCB0LCByLCBxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsTXVsdGlUZXhDb29yZDRmQVJCKEdMX1RFWFRVUkUwX0FSQiArIHRleHR1cmVfaWR4LCBzLCB0LCByLCBxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRleENvb3JkNGYocywgdCwgciwgcSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlNob3VsZCBub3QgZ2V0IGhlcmUgYXMgY29vcmRzVG9Vc2UgaXMgdHdvIGJpdHMgb25seSAoJXgpIVxuIiwgY29vcmRzVG9Vc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gLyogRW5kIG9mIHRleHR1cmVzICovCgogICAgICAgIC8qIERpZmZ1c2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgICBpZiAoZGlmZnVzZSkgewogICAgICAgICAgICBEV09SRCAqcHRyVG9Db29yZHMgPSAoRFdPUkQgKikoZGlmZnVzZSArIChTa2lwblN0cmlkZXMgKiBzZC0+dS5zLmRpZmZ1c2UuZHdTdHJpZGUpKTsKICAgICAgICAgICAgZGlmZnVzZUNvbG9yID0gcHRyVG9Db29yZHNbMF07CiAgICAgICAgICAgIFZUUkFDRSgoImRpZmZ1c2VDb2xvcj0lbHhcbiIsIGRpZmZ1c2VDb2xvcikpOwoKICAgICAgICAgICAgZ2xDb2xvcjR1YihEM0RDT0xPUl9CX1IoZGlmZnVzZUNvbG9yKSwKCQkgICAgIEQzRENPTE9SX0JfRyhkaWZmdXNlQ29sb3IpLAoJCSAgICAgRDNEQ09MT1JfQl9CKGRpZmZ1c2VDb2xvciksCgkJICAgICBEM0RDT0xPUl9CX0EoZGlmZnVzZUNvbG9yKSk7CiAgICAgICAgICAgIFZUUkFDRSgoImdsQ29sb3I0dWI6IHIsZyxiLGE9JWx1LCVsdSwlbHUsJWx1XG4iLCAKICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9CX1IoZGlmZnVzZUNvbG9yKSwKCQkgICAgRDNEQ09MT1JfQl9HKGRpZmZ1c2VDb2xvciksCgkJICAgIEQzRENPTE9SX0JfQihkaWZmdXNlQ29sb3IpLAoJCSAgICBEM0RDT0xPUl9CX0EoZGlmZnVzZUNvbG9yKSkpOwoKICAgICAgICAgICAgaWYoVGhpcy0+YWN0aXZlQ29udGV4dC0+bnVtX3VudHJhY2tlZF9tYXRlcmlhbHMpIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgaTsKICAgICAgICAgICAgICAgIGZsb2F0IGNvbG9yWzRdOwogICAgICAgICAgICAgICAgY29sb3JbMF0gPSBEM0RDT0xPUl9CX1IoZGlmZnVzZUNvbG9yKSAvIDI1NS4wOwogICAgICAgICAgICAgICAgY29sb3JbMV0gPSBEM0RDT0xPUl9CX0coZGlmZnVzZUNvbG9yKSAvIDI1NS4wOwogICAgICAgICAgICAgICAgY29sb3JbMl0gPSBEM0RDT0xPUl9CX0IoZGlmZnVzZUNvbG9yKSAvIDI1NS4wOwogICAgICAgICAgICAgICAgY29sb3JbM10gPSBEM0RDT0xPUl9CX0EoZGlmZnVzZUNvbG9yKSAvIDI1NS4wOwoKICAgICAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IFRoaXMtPmFjdGl2ZUNvbnRleHQtPm51bV91bnRyYWNrZWRfbWF0ZXJpYWxzOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBnbE1hdGVyaWFsZnYoR0xfRlJPTlRfQU5EX0JBQ0ssIFRoaXMtPmFjdGl2ZUNvbnRleHQtPnVudHJhY2tlZF9tYXRlcmlhbHNbaV0sIGNvbG9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogU3BlY3VsYXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgIGlmIChzcGVjdWxhcikgewogICAgICAgICAgICBEV09SRCAqcHRyVG9Db29yZHMgPSAoRFdPUkQgKikoc3BlY3VsYXIgKyAoU2tpcG5TdHJpZGVzICogc2QtPnUucy5zcGVjdWxhci5kd1N0cmlkZSkpOwogICAgICAgICAgICBzcGVjdWxhckNvbG9yID0gcHRyVG9Db29yZHNbMF07CiAgICAgICAgICAgIFZUUkFDRSgoInNwZWN1bGFyQ29sb3I9JWx4XG4iLCBzcGVjdWxhckNvbG9yKSk7CgogICAgICAgICAgICAvKiBzcGVjaWFsIGNhc2Ugd2hlcmUgdGhlIGZvZyBkZW5zaXR5IGlzIHN0b3JlZCBpbiB0aGUgc3BlY3VsYXIgYWxwaGEgY2hhbm5lbCAqLwogICAgICAgICAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfRk9HRU5BQkxFXSAmJgogICAgICAgICAgICAgIChUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfRk9HVkVSVEVYTU9ERV0gPT0gV0lORUQzREZPR19OT05FIHx8IHNkLT51LnMucG9zaXRpb24uZHdUeXBlID09IFdJTkVEM0RERUNMVFlQRV9GTE9BVDQgKSYmCiAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX0ZPR1RBQkxFTU9ERV0gPT0gV0lORUQzREZPR19OT05FKSB7CiAgICAgICAgICAgICAgICBpZihHTF9TVVBQT1JUKEVYVF9GT0dfQ09PUkQpKSB7CiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEZvZ0Nvb3JkZkVYVChzcGVjdWxhckNvbG9yID4+IDI0KSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgICAgICAgICAgICAgICAgIGlmKCF3YXJuZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVE9ETzogVXNlIHRoZSBmb2cgdGFibGUgY29kZSBmcm9tIG9sZCBkZHJhdyAqLwogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiSW1wbGVtZW50IGZvZyBmb3IgdHJhbnNmb3JtZWQgdmVydGljZXMgaW4gc29mdHdhcmVcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICB3YXJuZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgVlRSQUNFKCgiZ2xTZWNvbmRhcnlDb2xvcjR1YjogcixnLGI9JWx1LCVsdSwlbHVcbiIsIAogICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0JfUihzcGVjdWxhckNvbG9yKSwgCiAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfQl9HKHNwZWN1bGFyQ29sb3IpLCAKICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9CX0Ioc3BlY3VsYXJDb2xvcikpKTsKICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoRVhUX1NFQ09OREFSWV9DT0xPUikpIHsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xTZWNvbmRhcnlDb2xvcjN1YkVYVCkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0JfUihzcGVjdWxhckNvbG9yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfQl9HKHNwZWN1bGFyQ29sb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9CX0Ioc3BlY3VsYXJDb2xvcikpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogRG8gbm90IHdvcnJ5IGlmIHNwZWN1bGFyIGNvbG91ciBtaXNzaW5nIGFuZCBkaXNhYmxlIHJlcXVlc3QgKi8KICAgICAgICAgICAgICAgIFZUUkFDRSgoIlNwZWN1bGFyIGNvbG9yIGV4dGVuc2lvbnMgbm90IHN1cHBsaWVkXG4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIE5vcm1hbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgIGlmIChub3JtYWwgIT0gTlVMTCkgewogICAgICAgICAgICBmbG9hdCAqcHRyVG9Db29yZHMgPSAoZmxvYXQgKikobm9ybWFsICsgKFNraXBuU3RyaWRlcyAqIHNkLT51LnMubm9ybWFsLmR3U3RyaWRlKSk7CgogICAgICAgICAgICBWVFJBQ0UoKCJnbE5vcm1hbDpueCxueSxuej0lZiwlZiwlZlxuIiwgcHRyVG9Db29yZHNbMF0sIHB0clRvQ29vcmRzWzFdLCBwdHJUb0Nvb3Jkc1syXSkpOwogICAgICAgICAgICBnbE5vcm1hbDNmKHB0clRvQ29vcmRzWzBdLCBwdHJUb0Nvb3Jkc1sxXSwgcHRyVG9Db29yZHNbMl0pOwogICAgICAgIH0KCiAgICAgICAgLyogUG9zaXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgICBpZiAocG9zaXRpb24pIHsKICAgICAgICAgICAgZmxvYXQgKnB0clRvQ29vcmRzID0gKGZsb2F0ICopKHBvc2l0aW9uICsgKFNraXBuU3RyaWRlcyAqIHNkLT51LnMucG9zaXRpb24uZHdTdHJpZGUpKTsKICAgICAgICAgICAgeCA9IHB0clRvQ29vcmRzWzBdOwogICAgICAgICAgICB5ID0gcHRyVG9Db29yZHNbMV07CiAgICAgICAgICAgIHogPSBwdHJUb0Nvb3Jkc1syXTsKICAgICAgICAgICAgcmh3ID0gMS4wOwogICAgICAgICAgICBWVFJBQ0UoKCJ4LHksej0lZiwlZiwlZlxuIiwgeCx5LHopKTsKCiAgICAgICAgICAgIC8qIFJIVyBmb2xsb3dzLCBvbmx5IGlmIHRyYW5zZm9ybWVkLCBpZSA0IGZsb2F0cyB3ZXJlIHByb3ZpZGVkICovCiAgICAgICAgICAgIGlmIChzZC0+dS5zLnBvc2l0aW9uX3RyYW5zZm9ybWVkKSB7CiAgICAgICAgICAgICAgICByaHcgPSBwdHJUb0Nvb3Jkc1szXTsKICAgICAgICAgICAgICAgIFZUUkFDRSgoInJodz0lZlxuIiwgcmh3KSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgxLjBmID09IHJodyB8fCAoKHJodyA8IGVwcykgJiYgKHJodyA+IC1lcHMpKSkgewogICAgICAgICAgICAgICAgVlRSQUNFKCgiVmVydGV4OiBnbFZlcnRleDp4LHksej0lZiwlZiwlZlxuIiwgeCx5LHopKTsKICAgICAgICAgICAgICAgIGdsVmVydGV4M2YoeCwgeSwgeik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBHTGZsb2F0IHcgPSAxLjAgLyByaHc7CiAgICAgICAgICAgICAgICBWVFJBQ0UoKCJWZXJ0ZXg6IGdsVmVydGV4OngseSx6PSVmLCVmLCVmIC8gcmh3PSVmXG4iLCB4LHkseixyaHcpKTsKICAgICAgICAgICAgICAgIGdsVmVydGV4NGYoeCp3LCB5KncsIHoqdywgdyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIEZvciBub24gaW5kZXhlZCBtb2RlLCBzdGVwIG9udG8gbmV4dCBwYXJ0cyAqLwogICAgICAgIGlmIChpZHhEYXRhID09IE5VTEwpIHsKICAgICAgICAgICAgKytTa2lwblN0cmlkZXM7CiAgICAgICAgfQogICAgfQoKICAgIGdsRW5kKCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmQgYW5kIHByZXZpb3VzIGNhbGxzIik7Cn0KCnN0YXRpYyB2b2lkIGRlcHRoX2JsdChJV2luZUQzRERldmljZSAqaWZhY2UsIEdMdWludCB0ZXh0dXJlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBHTGludCBvbGRfYmluZGluZyA9IDA7CgogICAgZ2xQdXNoQXR0cmliKEdMX0VOQUJMRV9CSVQgfCBHTF9ERVBUSF9CVUZGRVJfQklUIHwgR0xfQ09MT1JfQlVGRkVSX0JJVCk7CgogICAgZ2xEaXNhYmxlKEdMX0NVTExfRkFDRSk7CiAgICBnbEVuYWJsZShHTF9CTEVORCk7CiAgICBnbERpc2FibGUoR0xfQUxQSEFfVEVTVCk7CiAgICBnbERpc2FibGUoR0xfU0NJU1NPUl9URVNUKTsKICAgIGdsRGlzYWJsZShHTF9TVEVOQ0lMX1RFU1QpOwogICAgZ2xFbmFibGUoR0xfREVQVEhfVEVTVCk7CiAgICBnbERlcHRoRnVuYyhHTF9BTFdBWVMpOwogICAgZ2xCbGVuZEZ1bmMoR0xfWkVSTywgR0xfT05FKTsKCiAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HXzJELCAmb2xkX2JpbmRpbmcpOwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCB0ZXh0dXJlKTsKICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwoKICAgIFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5zaGFkZXJfc2VsZWN0X2RlcHRoX2JsdChpZmFjZSk7CgogICAgZ2xCZWdpbihHTF9UUklBTkdMRV9TVFJJUCk7CiAgICBnbFZlcnRleDJmKC0xLjBmLCAtMS4wZik7CiAgICBnbFZlcnRleDJmKDEuMGYsIC0xLjBmKTsKICAgIGdsVmVydGV4MmYoLTEuMGYsIDEuMGYpOwogICAgZ2xWZXJ0ZXgyZigxLjBmLCAxLjBmKTsKICAgIGdsRW5kKCk7CgogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBvbGRfYmluZGluZyk7CgogICAgZ2xQb3BBdHRyaWIoKTsKCiAgICAvKiBSZXNlbGVjdCB0aGUgb2xkIHNoYWRlcnMuIFRoZXJlIGRvZXNuJ3Qgc2VlbSB0byBiZSBhbnkgZ2xQdXNoQXR0cmliIGJpdCBmb3IgYXJiIHNoYWRlcnMsCiAgICAgKiBhbmQgdGhpcyBzZWVtcyBlYXNpZXIgYW5kIG1vcmUgZWZmaWNpZW50IHRoYW4gcHJvdmlkaW5nIHRoZSBzaGFkZXIgYmFja2VuZCB3aXRoIGEgcHJpdmF0ZQogICAgICogc3RvcmFnZSB0byByZWFkIGFuZCByZXN0b3JlIHRoZSBvbGQgc2hhZGVyIHNldHRpbmdzCiAgICAgKi8KICAgIFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5zaGFkZXJfc2VsZWN0KGlmYWNlLCB1c2VfcHMoVGhpcyksIHVzZV92cyhUaGlzKSk7Cn0KCnN0YXRpYyB2b2lkIGRlcHRoX2NvcHkoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpkZXB0aF9zdGVuY2lsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyOwoKICAgIC8qIE9ubHkgY29weSB0aGUgZGVwdGggYnVmZmVyIGlmIHRoZXJlIGlzIG9uZS4gKi8KICAgIGlmICghZGVwdGhfc3RlbmNpbCkgcmV0dXJuOwoKICAgIC8qIFRPRE86IE1ha2UgdGhpcyB3b3JrIGZvciBtb2RlcyBvdGhlciB0aGFuIEZCTyAqLwogICAgaWYgKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlICE9IE9STV9GQk8pIHJldHVybjsKCiAgICBpZiAoZGVwdGhfc3RlbmNpbC0+Y3VycmVudF9yZW5kZXJidWZmZXIpIHsKICAgICAgICBGSVhNRSgiTm90IHN1cHBvcnRlZCB3aXRoIGZpeGVkIHVwIGRlcHRoIHN0ZW5jaWxcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgIHN0YXRpYyBHTHVpbnQgdG1wX3RleHR1cmUgPSAwOwogICAgICAgIEdMaW50IG9sZF9iaW5kaW5nID0gMDsKCiAgICAgICAgVFJBQ0UoIkNvcHlpbmcgb25zY3JlZW4gZGVwdGggYnVmZmVyIHRvIG9mZnNjcmVlbiBzdXJmYWNlXG4iKTsKCiAgICAgICAgaWYgKCF0bXBfdGV4dHVyZSkgewogICAgICAgICAgICBnbEdlblRleHR1cmVzKDEsICZ0bXBfdGV4dHVyZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBOb3RlIHRoYXQgd2UgdXNlIGRlcHRoX2JsdCBoZXJlIGFzIHdlbGwsIHJhdGhlciB0aGFuIGdsQ29weVRleEltYWdlMkQKICAgICAgICAgKiBkaXJlY3RseSBvbiB0aGUgRkJPIHRleHR1cmUuIFRoYXQncyBiZWNhdXNlIHdlIG5lZWQgdG8gZmxpcC4gKi8KICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HXzJELCAmb2xkX2JpbmRpbmcpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdG1wX3RleHR1cmUpOwogICAgICAgIGdsQ29weVRleEltYWdlMkQoZGVwdGhfc3RlbmNpbC0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICBkZXB0aF9zdGVuY2lsLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgZGVwdGhfc3RlbmNpbC0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLAogICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBkZXB0aF9zdGVuY2lsLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgIGRlcHRoX3N0ZW5jaWwtPmN1cnJlbnREZXNjLkhlaWdodCwKICAgICAgICAgICAgICAgIDApOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9ERVBUSF9URVhUVVJFX01PREVfQVJCLCBHTF9MVU1JTkFOQ0UpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgb2xkX2JpbmRpbmcpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgVGhpcy0+ZmJvKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKICAgICAgICBkZXB0aF9ibHQoaWZhY2UsIHRtcF90ZXh0dXJlKTsKICAgICAgICBjaGVja0dMY2FsbCgiZGVwdGhfYmx0Iik7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJDb3B5aW5nIG9mZnNjcmVlbiBzdXJmYWNlIHRvIG9uc2NyZWVuIGRlcHRoIGJ1ZmZlclxuIik7CgogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKICAgICAgICBkZXB0aF9ibHQoaWZhY2UsIGRlcHRoX3N0ZW5jaWwtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJkZXB0aF9ibHQiKTsKICAgIH0KfQoKc3RhdGljIGlubGluZSB2b2lkIGRyYXdTdHJpZGVkSW5zdGFuY2VkKElXaW5lRDNERGV2aWNlICppZmFjZSwgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKnNkLCBVSU5UIG51bWJlck9mVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMZW51bSBnbFByaW1pdGl2ZVR5cGUsIGNvbnN0IHZvaWQgKmlkeERhdGEsIHNob3J0IGlkeFNpemUsIFVMT05HIG1pbkluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyBzdGFydElkeCwgVUxPTkcgc3RhcnRWZXJ0ZXgpIHsKICAgIFVJTlQgbnVtSW5zdGFuY2VzID0gMDsKICAgIGludCBudW1JbnN0YW5jZWRBdHRyaWJzID0gMCwgaSwgajsKICAgIFVJTlQgaW5zdGFuY2VkRGF0YVtzaXplb2Yoc2QtPnUuaW5wdXQpIC8gc2l6ZW9mKHNkLT51LmlucHV0WzBdKSAvKiAxNiAqL107CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCAqc3RhdGVibG9jayA9IFRoaXMtPnN0YXRlQmxvY2s7CgogICAgaWYgKGlkeFNpemUgPT0gMCkgewogICAgICAgIC8qIFRoaXMgaXMgYSBuYXN0eSB0aGluZy4gTVNETiBzYXlzIG5vIGhhcmR3YXJlIHN1cHBvcnRzIHRoYXQgYW5kIGFwcHMgaGF2ZSB0byB1c2Ugc29mdHdhcmUgdmVydGV4IHByb2Nlc3NpbmcuCiAgICAgICAgICogV2UgZG9uJ3Qgc3VwcG9ydCB0aGlzIGZvciBub3cKICAgICAgICAgKgogICAgICAgICAqIFNob3VsZG4ndCBiZSB0b28gaGFyZCB0byBzdXBwb3J0IHdpdGggb3BlbmdsLCBpbiB0aGVvcnkganVzdCBjYWxsIGdsRHJhd0FycmF5cyBpbnN0ZWFkIG9mIGRyYXdFbGVtZW50cy4KICAgICAgICAgKiBCdXQgdGhlIFN0cmVhbVNvdXJjZUZyZXEgdmFsdWUgaGFzIGEgZGlmZmVyZW50IG1lYW5pbmcgaW4gdGhhdCBzaXR1YXRpb24uCiAgICAgICAgICovCiAgICAgICAgRklYTUUoIk5vbi1pbmRleGVkIGluc3RhbmNlZCBkcmF3aW5nIGlzIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IGdsRWxlbWVudHMoJXgsICVkLCAlZCwgLi4uKVxuIiwgVGhpcywgZ2xQcmltaXRpdmVUeXBlLCBudW1iZXJPZlZlcnRpY2VzLCBtaW5JbmRleCk7CiAgICBpZHhEYXRhID0gaWR4RGF0YSA9PSAodm9pZCAqKS0xID8gTlVMTCA6IGlkeERhdGE7CgogICAgLyogRmlyc3QsIGZpZ3VyZSBvdXQgaG93IG1hbnkgaW5zdGFuY2VzIHdlIGhhdmUgdG8gZHJhdyAqLwogICAgZm9yKGkgPSAwOyBpIDwgTUFYX1NUUkVBTVM7IGkrKykgewogICAgICAgIC8qIExvb2sgYXQgYWxsIG5vbi1pbnN0YW5jZWQgc3RyZWFtcyAqLwogICAgICAgIGlmKCEoc3RhdGVibG9jay0+c3RyZWFtRmxhZ3NbaV0gJiBXSU5FRDNEU1RSRUFNU09VUkNFX0lOU1RBTkNFREFUQSkgJiYKICAgICAgICAgICBzdGF0ZWJsb2NrLT5zdHJlYW1Tb3VyY2VbaV0pIHsKICAgICAgICAgICAgaW50IGluc3QgPSBzdGF0ZWJsb2NrLT5zdHJlYW1GcmVxW2ldOwoKICAgICAgICAgICAgaWYobnVtSW5zdGFuY2VzICYmIGluc3QgIT0gbnVtSW5zdGFuY2VzKSB7CiAgICAgICAgICAgICAgICBFUlIoIlR3byBzdHJlYW1zIHNwZWNpZnkgYSBkaWZmZXJlbnQgbnVtYmVyIG9mIGluc3RhbmNlcy4gR290ICVkLCBuZXcgaXMgJWRcbiIsIG51bUluc3RhbmNlcywgaW5zdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbnVtSW5zdGFuY2VzID0gaW5zdDsKICAgICAgICB9CiAgICB9CgogICAgZm9yKGkgPSAwOyBpIDwgc2l6ZW9mKHNkLT51LmlucHV0KSAvIHNpemVvZihzZC0+dS5pbnB1dFswXSk7IGkrKykgewogICAgICAgIGlmKHN0YXRlYmxvY2stPnN0cmVhbUZsYWdzW3NkLT51LmlucHV0W2ldLnN0cmVhbU5vXSAmIFdJTkVEM0RTVFJFQU1TT1VSQ0VfSU5TVEFOQ0VEQVRBKSB7CiAgICAgICAgICAgIGluc3RhbmNlZERhdGFbbnVtSW5zdGFuY2VkQXR0cmlic10gPSBpOwogICAgICAgICAgICBudW1JbnN0YW5jZWRBdHRyaWJzKys7CiAgICAgICAgfQogICAgfQoKICAgIC8qIG5vdyBkcmF3IG51bUluc3RhbmNlcyBpbnN0YW5jZXMgOi0pICovCiAgICBmb3IoaSA9IDA7IGkgPCBudW1JbnN0YW5jZXM7IGkrKykgewogICAgICAgIC8qIFNwZWNpZnkgdGhlIGluc3RhbmNlZCBhdHRyaWJ1dGVzIHVzaW5nIGltbWVkaWF0ZSBtb2RlIGNhbGxzICovCiAgICAgICAgZm9yKGogPSAwOyBqIDwgbnVtSW5zdGFuY2VkQXR0cmliczsgaisrKSB7CiAgICAgICAgICAgIEJZVEUgKnB0ciA9IHNkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLmxwRGF0YSArCiAgICAgICAgICAgICAgICAgICAgICAgIHNkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLmR3U3RyaWRlICogaSArCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlYmxvY2stPnN0cmVhbU9mZnNldFtzZC0+dS5pbnB1dFtpbnN0YW5jZWREYXRhW2pdXS5zdHJlYW1Ob107CiAgICAgICAgICAgIGlmKHNkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLlZCTykgewogICAgICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICp2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgc3RhdGVibG9jay0+c3RyZWFtU291cmNlW3NkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLnN0cmVhbU5vXTsKICAgICAgICAgICAgICAgIHB0ciArPSAobG9uZykgdmItPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoKHNkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLmR3VHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQxOgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWIxZnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKGZsb2F0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQyOgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWIyZnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKGZsb2F0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWIzZnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKGZsb2F0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQ0OgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWI0ZnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKGZsb2F0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX1VCWVRFNDoKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVmVydGV4QXR0cmliNHVidkFSQihpbnN0YW5jZWREYXRhW2pdLCBwdHIpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX1VCWVRFNE46CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjoKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVmVydGV4QXR0cmliNE51YnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgcHRyKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfU0hPUlQyOgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWI0c3ZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKEdMc2hvcnQgKikgcHRyKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9TSE9SVDQ6CiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFZlcnRleEF0dHJpYjRzdkFSQihpbnN0YW5jZWREYXRhW2pdLCAoR0xzaG9ydCAqKSBwdHIpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9TSE9SVDJOOgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEdMc2hvcnQgc1s0XSA9IHsoKHNob3J0ICopIHB0cilbMF0sICgoc2hvcnQgKikgcHRyKVsxXSwgMCwgMX07CiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFZlcnRleEF0dHJpYjROc3ZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgcykpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfVVNIT1JUMk46CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgR0x1c2hvcnQgc1s0XSA9IHsoKHVuc2lnbmVkIHNob3J0ICopIHB0cilbMF0sICgodW5zaWduZWQgc2hvcnQgKikgcHRyKVsxXSwgMCwgMX07CiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFZlcnRleEF0dHJpYjROdXN2QVJCKGluc3RhbmNlZERhdGFbal0sIHMpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX1NIT1JUNE46CiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFZlcnRleEF0dHJpYjROc3ZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKEdMc2hvcnQgKikgcHRyKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9VU0hPUlQ0TjoKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVmVydGV4QXR0cmliNE51c3ZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKEdMdXNob3J0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX1VERUMzOgogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cmUgYWJvdXQgV0lORUQzRERFQ0xUWVBFX1VERUMzXG4iKTsKICAgICAgICAgICAgICAgICAgICAvKmdsVmVydGV4QXR0cmliM3VzdkFSQihpbnN0YW5jZWREYXRhW2pdLCAoR0x1c2hvcnQgKikgcHRyKTsgRG9lcyBub3QgZXhpc3QgKi8KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX0RFQzNOOgogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cmUgYWJvdXQgV0lORUQzRERFQ0xUWVBFX0RFQzNOXG4iKTsKICAgICAgICAgICAgICAgICAgICAvKmdsVmVydGV4QXR0cmliM051c3ZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKEdMdXNob3J0ICopIHB0cik7IERvZXMgbm90IGV4aXN0ICovCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQxNl8yOgogICAgICAgICAgICAgICAgICAgIC8qIEFyZSB0aG9zZSAxNiBiaXQgZmxvYXRzLiBDIGRvZXNuJ3QgaGF2ZSBhIDE2IGJpdCBmbG9hdCB0eXBlLiBJIGNvdWxkIHJlYWQgdGhlIHNpbmdsZSBiaXRzIGFuZCBjYWxjdWxhdGUgYSA0CiAgICAgICAgICAgICAgICAgICAgICogYnl0ZSBmbG9hdCBhY2NvcmRpbmcgdG8gdGhlIElFRUUgc3RhbmRhcmQKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChOVl9IQUxGX0ZMT0FUKSkgewogICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVmVydGV4QXR0cmliMmh2TlYoaW5zdGFuY2VkRGF0YVtqXSwgKEdMaGFsZk5WICopcHRyKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIFdJTkVEM0RERUNMVFlQRV9GTE9BVDE2XzJcbiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX0ZMT0FUMTZfNDoKICAgICAgICAgICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChOVl9IQUxGX0ZMT0FUKSkgewogICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVmVydGV4QXR0cmliNGh2TlYoaW5zdGFuY2VkRGF0YVtqXSwgKEdMaGFsZk5WICopcHRyKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIFdJTkVEM0RERUNMVFlQRV9GTE9BVDE2XzRcbiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9VTlVTRUQ6CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBkZWNsYXJhdGlvbiBpbiBpbnN0YW5jZWQgYXR0cmlidXRlc1xuIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGdsRHJhd0VsZW1lbnRzKGdsUHJpbWl0aXZlVHlwZSwgbnVtYmVyT2ZWZXJ0aWNlcywgaWR4U2l6ZSA9PSAyID8gR0xfVU5TSUdORURfU0hPUlQgOiBHTF9VTlNJR05FRF9JTlQsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKilpZHhEYXRhKyhpZHhTaXplICogc3RhcnRJZHgpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3RWxlbWVudHMiKTsKICAgIH0KfQoKc3RhdGljIGlubGluZSB2b2lkIHJlbW92ZV92Ym9zKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKnMpIHsKICAgIHVuc2lnbmVkIGNoYXIgaTsKICAgIElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqdmI7CgogICAgaWYocy0+dS5zLnBvc2l0aW9uLlZCTykgewogICAgICAgIHZiID0gKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbcy0+dS5zLnBvc2l0aW9uLnN0cmVhbU5vXTsKICAgICAgICBzLT51LnMucG9zaXRpb24uVkJPID0gMDsKICAgICAgICBzLT51LnMucG9zaXRpb24ubHBEYXRhID0gKEJZVEUgKikgKCh1bnNpZ25lZCBsb25nKSBzLT51LnMucG9zaXRpb24ubHBEYXRhICsgKHVuc2lnbmVkIGxvbmcpIHZiLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgfQogICAgaWYocy0+dS5zLmJsZW5kV2VpZ2h0cy5WQk8pIHsKICAgICAgICB2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3MtPnUucy5ibGVuZFdlaWdodHMuc3RyZWFtTm9dOwogICAgICAgIHMtPnUucy5ibGVuZFdlaWdodHMuVkJPID0gMDsKICAgICAgICBzLT51LnMuYmxlbmRXZWlnaHRzLmxwRGF0YSA9IChCWVRFICopICgodW5zaWduZWQgbG9uZykgcy0+dS5zLmJsZW5kV2VpZ2h0cy5scERhdGEgKyAodW5zaWduZWQgbG9uZykgdmItPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICB9CiAgICBpZihzLT51LnMuYmxlbmRNYXRyaXhJbmRpY2VzLlZCTykgewogICAgICAgIHZiID0gKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbcy0+dS5zLmJsZW5kTWF0cml4SW5kaWNlcy5zdHJlYW1Ob107CiAgICAgICAgcy0+dS5zLmJsZW5kTWF0cml4SW5kaWNlcy5WQk8gPSAwOwogICAgICAgIHMtPnUucy5ibGVuZE1hdHJpeEluZGljZXMubHBEYXRhID0gKEJZVEUgKikgKCh1bnNpZ25lZCBsb25nKSBzLT51LnMuYmxlbmRNYXRyaXhJbmRpY2VzLmxwRGF0YSArICh1bnNpZ25lZCBsb25nKSB2Yi0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIH0KICAgIGlmKHMtPnUucy5ub3JtYWwuVkJPKSB7CiAgICAgICAgdmIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzLT51LnMubm9ybWFsLnN0cmVhbU5vXTsKICAgICAgICBzLT51LnMubm9ybWFsLlZCTyA9IDA7CiAgICAgICAgcy0+dS5zLm5vcm1hbC5scERhdGEgPSAoQllURSAqKSAoKHVuc2lnbmVkIGxvbmcpIHMtPnUucy5ub3JtYWwubHBEYXRhICsgKHVuc2lnbmVkIGxvbmcpIHZiLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgfQogICAgaWYocy0+dS5zLnBTaXplLlZCTykgewogICAgICAgIHZiID0gKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbcy0+dS5zLnBTaXplLnN0cmVhbU5vXTsKICAgICAgICBzLT51LnMucFNpemUuVkJPID0gMDsKICAgICAgICBzLT51LnMucFNpemUubHBEYXRhID0gKEJZVEUgKikgKCh1bnNpZ25lZCBsb25nKSBzLT51LnMucFNpemUubHBEYXRhICsgKHVuc2lnbmVkIGxvbmcpIHZiLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgfQogICAgaWYocy0+dS5zLmRpZmZ1c2UuVkJPKSB7CiAgICAgICAgdmIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzLT51LnMuZGlmZnVzZS5zdHJlYW1Ob107CiAgICAgICAgcy0+dS5zLmRpZmZ1c2UuVkJPID0gMDsKICAgICAgICBzLT51LnMuZGlmZnVzZS5scERhdGEgPSAoQllURSAqKSAoKHVuc2lnbmVkIGxvbmcpIHMtPnUucy5kaWZmdXNlLmxwRGF0YSArICh1bnNpZ25lZCBsb25nKSB2Yi0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIH0KICAgIGlmKHMtPnUucy5zcGVjdWxhci5WQk8pIHsKICAgICAgICB2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3MtPnUucy5zcGVjdWxhci5zdHJlYW1Ob107CiAgICAgICAgcy0+dS5zLnNwZWN1bGFyLlZCTyA9IDA7CiAgICAgICAgcy0+dS5zLnNwZWN1bGFyLmxwRGF0YSA9IChCWVRFICopICgodW5zaWduZWQgbG9uZykgcy0+dS5zLnNwZWN1bGFyLmxwRGF0YSArICh1bnNpZ25lZCBsb25nKSB2Yi0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIH0KICAgIGZvcihpID0gMDsgaSA8IFdJTkVEM0REUF9NQVhURVhDT09SRDsgaSsrKSB7CiAgICAgICAgaWYocy0+dS5zLnRleENvb3Jkc1tpXS5WQk8pIHsKICAgICAgICAgICAgdmIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzLT51LnMudGV4Q29vcmRzW2ldLnN0cmVhbU5vXTsKICAgICAgICAgICAgcy0+dS5zLnRleENvb3Jkc1tpXS5WQk8gPSAwOwogICAgICAgICAgICBzLT51LnMudGV4Q29vcmRzW2ldLmxwRGF0YSA9IChCWVRFICopICgodW5zaWduZWQgbG9uZykgcy0+dS5zLnRleENvb3Jkc1tpXS5scERhdGEgKyAodW5zaWduZWQgbG9uZykgdmItPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgfQogICAgfQogICAgaWYocy0+dS5zLnBvc2l0aW9uMi5WQk8pIHsKICAgICAgICB2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3MtPnUucy5wb3NpdGlvbjIuc3RyZWFtTm9dOwogICAgICAgIHMtPnUucy5wb3NpdGlvbjIuVkJPID0gMDsKICAgICAgICBzLT51LnMucG9zaXRpb24yLmxwRGF0YSA9IChCWVRFICopICgodW5zaWduZWQgbG9uZykgcy0+dS5zLnBvc2l0aW9uMi5scERhdGEgKyAodW5zaWduZWQgbG9uZykgdmItPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICB9CiAgICBpZihzLT51LnMubm9ybWFsMi5WQk8pIHsKICAgICAgICB2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3MtPnUucy5ub3JtYWwyLnN0cmVhbU5vXTsKICAgICAgICBzLT51LnMubm9ybWFsMi5WQk8gPSAwOwogICAgICAgIHMtPnUucy5ub3JtYWwyLmxwRGF0YSA9IChCWVRFICopICgodW5zaWduZWQgbG9uZykgcy0+dS5zLm5vcm1hbDIubHBEYXRhICsgKHVuc2lnbmVkIGxvbmcpIHZiLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgfQogICAgaWYocy0+dS5zLnRhbmdlbnQuVkJPKSB7CiAgICAgICAgdmIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzLT51LnMudGFuZ2VudC5zdHJlYW1Ob107CiAgICAgICAgcy0+dS5zLnRhbmdlbnQuVkJPID0gMDsKICAgICAgICBzLT51LnMudGFuZ2VudC5scERhdGEgPSAoQllURSAqKSAoKHVuc2lnbmVkIGxvbmcpIHMtPnUucy50YW5nZW50LmxwRGF0YSArICh1bnNpZ25lZCBsb25nKSB2Yi0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIH0KICAgIGlmKHMtPnUucy5iaW5vcm1hbC5WQk8pIHsKICAgICAgICB2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3MtPnUucy5iaW5vcm1hbC5zdHJlYW1Ob107CiAgICAgICAgcy0+dS5zLmJpbm9ybWFsLlZCTyA9IDA7CiAgICAgICAgcy0+dS5zLmJpbm9ybWFsLmxwRGF0YSA9IChCWVRFICopICgodW5zaWduZWQgbG9uZykgcy0+dS5zLmJpbm9ybWFsLmxwRGF0YSArICh1bnNpZ25lZCBsb25nKSB2Yi0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIH0KICAgIGlmKHMtPnUucy50ZXNzRmFjdG9yLlZCTykgewogICAgICAgIHZiID0gKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbcy0+dS5zLnRlc3NGYWN0b3Iuc3RyZWFtTm9dOwogICAgICAgIHMtPnUucy50ZXNzRmFjdG9yLlZCTyA9IDA7CiAgICAgICAgcy0+dS5zLnRlc3NGYWN0b3IubHBEYXRhID0gKEJZVEUgKikgKCh1bnNpZ25lZCBsb25nKSBzLT51LnMudGVzc0ZhY3Rvci5scERhdGEgKyAodW5zaWduZWQgbG9uZykgdmItPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICB9CiAgICBpZihzLT51LnMuZm9nLlZCTykgewogICAgICAgIHZiID0gKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbcy0+dS5zLmZvZy5zdHJlYW1Ob107CiAgICAgICAgcy0+dS5zLmZvZy5WQk8gPSAwOwogICAgICAgIHMtPnUucy5mb2cubHBEYXRhID0gKEJZVEUgKikgKCh1bnNpZ25lZCBsb25nKSBzLT51LnMuZm9nLmxwRGF0YSArICh1bnNpZ25lZCBsb25nKSB2Yi0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIH0KICAgIGlmKHMtPnUucy5kZXB0aC5WQk8pIHsKICAgICAgICB2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3MtPnUucy5kZXB0aC5zdHJlYW1Ob107CiAgICAgICAgcy0+dS5zLmRlcHRoLlZCTyA9IDA7CiAgICAgICAgcy0+dS5zLmRlcHRoLmxwRGF0YSA9IChCWVRFICopICgodW5zaWduZWQgbG9uZykgcy0+dS5zLmRlcHRoLmxwRGF0YSArICh1bnNpZ25lZCBsb25nKSB2Yi0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIH0KICAgIGlmKHMtPnUucy5zYW1wbGUuVkJPKSB7CiAgICAgICAgdmIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzLT51LnMuc2FtcGxlLnN0cmVhbU5vXTsKICAgICAgICBzLT51LnMuc2FtcGxlLlZCTyA9IDA7CiAgICAgICAgcy0+dS5zLnNhbXBsZS5scERhdGEgPSAoQllURSAqKSAoKHVuc2lnbmVkIGxvbmcpIHMtPnUucy5zYW1wbGUubHBEYXRhICsgKHVuc2lnbmVkIGxvbmcpIHZiLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgfQp9CgovKiBSb3V0aW5lIGNvbW1vbiB0byB0aGUgZHJhdyBwcmltaXRpdmUgYW5kIGRyYXcgaW5kZXhlZCBwcmltaXRpdmUgcm91dGluZXMgKi8Kdm9pZCBkcmF3UHJpbWl0aXZlKElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgIGludCBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgbG9uZyBOdW1QcmltaXRpdmVzLAogICAgICAgICAgICAgICAgICAgLyogZm9yIEluZGV4ZWQ6ICovCiAgICAgICAgICAgICAgICAgICBsb25nICBTdGFydFZlcnRleEluZGV4LAogICAgICAgICAgICAgICAgICAgVUlOVCAgbnVtYmVyT2ZWZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgIGxvbmcgIFN0YXJ0SWR4LAogICAgICAgICAgICAgICAgICAgc2hvcnQgaWR4U2l6ZSwKICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmlkeERhdGEsCiAgICAgICAgICAgICAgICAgICBpbnQgICBtaW5JbmRleCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAgICAgICAgICAgICpzd2FwY2hhaW47CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICAgICAgICAgICp0ZXh0dXJlID0gTlVMTDsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgICAgICAgICAgKnRhcmdldDsKICAgIGludCBpOwoKICAgIC8qIFNpZ25hbHMgb3RoZXIgbW9kdWxlcyB0aGF0IGEgZHJhd2luZyBpcyBpbiBwcm9ncmVzcyBhbmQgdGhlIHN0YXRlYmxvY2sgZmluYWxpemVkICovCiAgICBUaGlzLT5pc0luRHJhdyA9IFRSVUU7CgogICAgLyogSW52YWxpZGF0ZSB0aGUgYmFjayBidWZmZXIgbWVtb3J5IHNvIExvY2tSZWN0IHdpbGwgcmVhZCBpdCB0aGUgbmV4dCB0aW1lICovCiAgICBmb3IoaSA9IDA7IGkgPCBHTF9MSU1JVFMoYnVmZmVycyk7IGkrKykgewogICAgICAgIHRhcmdldCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFRoaXMtPnJlbmRlcl90YXJnZXRzW2ldOwoKICAgICAgICAvKiBUT0RPOiBPbmx5IGRvIGFsbCB0aGF0IGlmIHdlJ3JlIGdvaW5nIHRvIGNoYW5nZSBhbnl0aGluZwogICAgICAgICAqIFRleHR1cmUgY29udGFpbmVyIGRpcnRpZmljYXRpb24gZG9lcyBub3Qgd29yayBxdWl0ZSByaWdodCB5ZXQKICAgICAgICAgKi8KICAgICAgICBpZih0YXJnZXQgLyomJiB0YXJnZXQtPkZsYWdzICYgKFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lOU1lTTUVNKSovKSB7CiAgICAgICAgICAgIHN3YXBjaGFpbiA9IE5VTEw7CiAgICAgICAgICAgIHRleHR1cmUgPSBOVUxMOwoKICAgICAgICAgICAgaWYoaSA9PSAwKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKChJV2luZUQzRFN1cmZhY2UgKikgdGFyZ2V0LCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKCiAgICAgICAgICAgICAgICAvKiBOZWVkIHRoZSBzdXJmYWNlIGluIHRoZSBkcmF3YWJsZSEgKi8KICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oKElXaW5lRDNEU3VyZmFjZSAqKSB0YXJnZXQsIFNGTEFHX0lORFJBV0FCTEUsIE5VTEwpOwoKICAgICAgICAgICAgICAgIC8qIFRPRE86IE1vdmUgZmJvIGxvZ2ljIHRvIE1vZGlmeUxvY2F0aW9uICovCiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oKElXaW5lRDNEU3VyZmFjZSAqKSB0YXJnZXQsIFNGTEFHX0lORFJBV0FCTEUsIFRSVUUpOwogICAgICAgICAgICAgICAgaWYoc3dhcGNoYWluKSB7CiAgICAgICAgICAgICAgICAgICAgLyogT25zY3JlZW4gdGFyZ2V0LiBJbnZhbGlkYXRlIHN5c3RlbSBtZW1vcnkgY29weSBhbmQgdGV4dHVyZSBjb3B5ICovCiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlICE9IE9STV9GQk8pIHsKICAgICAgICAgICAgICAgICAgICAvKiBOb24tRkJPIHRhcmdldDogSW52YWxpZGF0ZSBzeXN0ZW0gY29weSwgdGV4dHVyZSBjb3B5IGFuZCBkaXJ0aWZ5IHRoZSBjb250YWluZXIgKi8KICAgICAgICAgICAgICAgICAgICAvKiBUT0RPOiBNb3ZlIGNvbnRhaW5lciBkaXJ0aWZpY2F0aW9uIHRvIE1vZGlmeUxvY2F0aW9uICovCiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcigoSVdpbmVEM0RTdXJmYWNlICopIHRhcmdldCwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmdGV4dHVyZSk7CgogICAgICAgICAgICAgICAgICAgIGlmKHRleHR1cmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9TZXREaXJ0eSh0ZXh0dXJlLCBUUlVFKTsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX1JlbGVhc2UodGV4dHVyZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKiBGQk8gb2Zmc2NyZWVuIHRhcmdldC4gVGV4dHVyZSA9PSBEcmF3YWJsZSAqLwogICAgICAgICAgICAgICAgICAgIHRhcmdldC0+RmxhZ3MgfD0gU0ZMQUdfSU5URVhUVVJFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogTXVzdCBiZSBhbiBmYm8gcmVuZGVyIHRhcmdldCAqLwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKChJV2luZUQzRFN1cmZhY2UgKikgdGFyZ2V0LCBTRkxBR19JTkRSQVdBQkxFLCBUUlVFKTsKICAgICAgICAgICAgICAgIHRhcmdldC0+RmxhZ3MgfD0gIFNGTEFHX0lOVEVYVFVSRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBPaywgd2Ugd2lsbCBiZSB1cGRhdGluZyB0aGUgc2NyZWVuIGZyb20gaGVyZSBvbndhcmRzIHNvIGdyYWIgdGhlIGxvY2sgKi8KCiAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgYXBwbHlfZmJvX3N0YXRlKGlmYWNlKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgfQoKICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSwgQ1RYVVNBR0VfRFJBV1BSSU0pOwogICAgRU5URVJfR0woKTsKCiAgICBpZiAoVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSA9PSBXSU5FRDNEX0RDU19DT1BZKSB7CiAgICAgICAgZGVwdGhfY29weShpZmFjZSk7CiAgICB9CiAgICBUaGlzLT5kZXB0aF9jb3B5X3N0YXRlID0gV0lORUQzRF9EQ1NfSU5JVElBTDsKCiAgICB7CiAgICAgICAgR0xlbnVtIGdsUHJpbVR5cGU7CiAgICAgICAgQk9PTCBlbXVsYXRpb24gPSBGQUxTRTsKICAgICAgICBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSAqc3RyaWRlZCA9ICZUaGlzLT5zdHJpZGVkX3N0cmVhbXM7CiAgICAgICAgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgc3RyaWRlZGxjbDsKICAgICAgICAvKiBPaywgV29yayBvdXQgd2hpY2ggcHJpbWl0aXZlIGlzIHJlcXVlc3RlZCBhbmQgaG93IG1hbnkgdmVydGV4ZXMgdGhhdAogICAgICAgICAgIHdpbGwgYmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgVUlOVCBjYWxjdWxhdGVkTnVtYmVyT2ZpbmRpY2VzID0gcHJpbWl0aXZlVG9HbChQcmltaXRpdmVUeXBlLCBOdW1QcmltaXRpdmVzLCAmZ2xQcmltVHlwZSk7CiAgICAgICAgaWYgKG51bWJlck9mVmVydGljZXMgPT0gMCApCiAgICAgICAgICAgIG51bWJlck9mVmVydGljZXMgPSBjYWxjdWxhdGVkTnVtYmVyT2ZpbmRpY2VzOwoKICAgICAgICBpZighdXNlX3ZzKFRoaXMpKSB7CiAgICAgICAgICAgIGlmKCFUaGlzLT5zdHJpZGVkX3N0cmVhbXMudS5zLnBvc2l0aW9uX3RyYW5zZm9ybWVkICYmIFRoaXMtPmFjdGl2ZUNvbnRleHQtPm51bV91bnRyYWNrZWRfbWF0ZXJpYWxzICYmCiAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfTElHSFRJTkddKSB7CiAgICAgICAgICAgICAgICBGSVhNRSgiVXNpbmcgc29mdHdhcmUgZW11bGF0aW9uIGJlY2F1c2Ugbm90IGFsbCBtYXRlcmlhbCBwcm9wZXJ0aWVzIGNvdWxkIGJlIHRyYWNrZWRcbiIpOwogICAgICAgICAgICAgICAgZW11bGF0aW9uID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKFRoaXMtPmFjdGl2ZUNvbnRleHQtPmZvZ19jb29yZCAmJiBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfRk9HRU5BQkxFXSkgewogICAgICAgICAgICAgICAgLyogRWl0aGVyIHdyaXRlIGEgcGlwZWxpbmUgcmVwbGFjZW1lbnQgc2hhZGVyIG9yIGNvbnZlcnQgdGhlIHNwZWN1bGFyIGFscGhhIGZyb20gdW5zaWduZWQgYnl0ZQogICAgICAgICAgICAgICAgICogdG8gYSBmbG9hdCBpbiB0aGUgdmVydGV4IGJ1ZmZlcgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBGSVhNRSgiVXNpbmcgc29mdHdhcmUgZW11bGF0aW9uIGJlY2F1c2UgbWFudWFsIGZvZyBjb29yZGluYXRlcyBhcmUgcHJvdmlkZWRcbiIpOwogICAgICAgICAgICAgICAgZW11bGF0aW9uID0gVFJVRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYoZW11bGF0aW9uKSB7CiAgICAgICAgICAgICAgICBzdHJpZGVkID0gJnN0cmlkZWRsY2w7CiAgICAgICAgICAgICAgICBtZW1jcHkoJnN0cmlkZWRsY2wsICZUaGlzLT5zdHJpZGVkX3N0cmVhbXMsIHNpemVvZihzdHJpZGVkbGNsKSk7CiAgICAgICAgICAgICAgICByZW1vdmVfdmJvcyhUaGlzLCAmc3RyaWRlZGxjbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChUaGlzLT51c2VEcmF3U3RyaWRlZFNsb3cgfHwgZW11bGF0aW9uKSB7CiAgICAgICAgICAgIC8qIEltbWVkaWF0ZSBtb2RlIGRyYXdpbmcgKi8KICAgICAgICAgICAgZHJhd1N0cmlkZWRTbG93KGlmYWNlLCBzdHJpZGVkLCBjYWxjdWxhdGVkTnVtYmVyT2ZpbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xQcmltVHlwZSwgaWR4RGF0YSwgaWR4U2l6ZSwgbWluSW5kZXgsIFN0YXJ0SWR4LCBTdGFydFZlcnRleEluZGV4KTsKICAgICAgICB9IGVsc2UgaWYoVGhpcy0+aW5zdGFuY2VkRHJhdykgewogICAgICAgICAgICAvKiBJbnN0YW5jaW5nIGVtdWxhdGlvbiB3aXRoIG1peGluZyBpbW1lZGlhdGUgbW9kZSBhbmQgYXJyYXlzICovCiAgICAgICAgICAgIGRyYXdTdHJpZGVkSW5zdGFuY2VkKGlmYWNlLCAmVGhpcy0+c3RyaWRlZF9zdHJlYW1zLCBjYWxjdWxhdGVkTnVtYmVyT2ZpbmRpY2VzLCBnbFByaW1UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4RGF0YSwgaWR4U2l6ZSwgbWluSW5kZXgsIFN0YXJ0SWR4LCBTdGFydFZlcnRleEluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBTaW1wbGUgYXJyYXkgZHJhdyBjYWxsICovCiAgICAgICAgICAgIGRyYXdTdHJpZGVkRmFzdChpZmFjZSwgY2FsY3VsYXRlZE51bWJlck9maW5kaWNlcywgZ2xQcmltVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkeERhdGEsIGlkeFNpemUsIG1pbkluZGV4LCBTdGFydElkeCwgU3RhcnRWZXJ0ZXhJbmRleCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEZpbnNoZWQgdXBkYXRpbmcgdGhlIHNjcmVlbiwgcmVzdG9yZSBsb2NrICovCiAgICBMRUFWRV9HTCgpOwogICAgVFJBQ0UoIkRvbmUgYWxsIGdsIGRyYXdpbmdcbiIpOwoKICAgIC8qIERpYWdub3N0aWNzICovCiNpZmRlZiBTSE9XX0ZSQU1FX01BS0VVUAogICAgewogICAgICAgIHN0YXRpYyBsb25nIGludCBwcmltQ291bnRlciA9IDA7CiAgICAgICAgLyogTk9URTogc2V0IHByaW1Db3VudGVyIHRvIHRoZSB2YWx1ZSByZXBvcnRlZCBieSBkcmF3cHJpbSAKICAgICAgICAgICBiZWZvcmUgeW91IHdhbnQgdG8gdG8gd3JpdGUgZnJhbWUgbWFrZXVwIHRvIC90bXAgKi8KICAgICAgICBpZiAocHJpbUNvdW50ZXIgPj0gMCkgewogICAgICAgICAgICBXSU5FRDNETE9DS0VEX1JFQ1QgcjsKICAgICAgICAgICAgY2hhciBidWZmZXJbODBdOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoVGhpcy0+cmVuZGVyVGFyZ2V0LCAmciwgTlVMTCwgV0lORUQzRExPQ0tfUkVBRE9OTFkpOwogICAgICAgICAgICBzcHJpbnRmKGJ1ZmZlciwgIi90bXAvYmFja2J1ZmZlcl8lZC50Z2EiLCBwcmltQ291bnRlcik7CiAgICAgICAgICAgIFRSQUNFKCJTYXZpbmcgc2NyZWVuc2hvdCAlc1xuIiwgYnVmZmVyKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NhdmVTbmFwc2hvdChUaGlzLT5yZW5kZXJUYXJnZXQsIGJ1ZmZlcik7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KFRoaXMtPnJlbmRlclRhcmdldCk7CgojaWZkZWYgU0hPV19URVhUVVJFX01BS0VVUAogICAgICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpwU3VyOwogICAgICAgICAgICBpbnQgdGV4dHVyZU5vOwogICAgICAgICAgICBmb3IgKHRleHR1cmVObyA9IDA7IHRleHR1cmVObyA8IE1BWF9DT01CSU5FRF9TQU1QTEVSUzsgKyt0ZXh0dXJlTm8pIHsKICAgICAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1t0ZXh0dXJlTm9dICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKGJ1ZmZlciwgIi90bXAvdGV4dHVyZV8lcF8lZF8lZC50Z2EiLCBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1t0ZXh0dXJlTm9dLCBwcmltQ291bnRlciwgdGV4dHVyZU5vKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiU2F2aW5nIHRleHR1cmUgJXNcbiIsIGJ1ZmZlcik7CiAgICAgICAgICAgICAgICAgICAgaWYgKElXaW5lRDNEQmFzZVRleHR1cmVfR2V0VHlwZShUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1t0ZXh0dXJlTm9dKSA9PSBXSU5FRDNEUlRZUEVfVEVYVFVSRSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX0dldFN1cmZhY2VMZXZlbCgoSVdpbmVEM0RUZXh0dXJlICopVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbdGV4dHVyZU5vXSwgMCwgJnBTdXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NhdmVTbmFwc2hvdChwU3VyLCBidWZmZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UocFN1cik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJiYXNlIFRleHR1cmUgaXNuJ3Qgb2YgdHlwZSB0ZXh0dXJlICVkXG4iLCBJV2luZUQzREJhc2VUZXh0dXJlX0dldFR5cGUoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbdGV4dHVyZU5vXSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgfQogICAgICAgIFRSQUNFKCJkcmF3cHJpbSAjJWRcbiIsIHByaW1Db3VudGVyKTsKICAgICAgICArK3ByaW1Db3VudGVyOwogICAgfQojZW5kaWYKCiAgICAvKiBDb250cm9sIGdvZXMgYmFjayB0byB0aGUgZGV2aWNlLCBzdGF0ZWJsb2NrIHZhbHVlcyBtYXkgY2hhbmdlIGFnYWluICovCiAgICBUaGlzLT5pc0luRHJhdyA9IEZBTFNFOwp9CgpzdGF0aWMgdm9pZCBub3JtYWxpemVfbm9ybWFsKGZsb2F0ICpuKSB7CiAgICBmbG9hdCBsZW5ndGggPSBuWzBdICogblswXSArIG5bMV0gKiBuWzFdICsgblsyXSAqIG5bMl07CiAgICBpZihsZW5ndGggPT0gMC4wKSByZXR1cm47CiAgICBsZW5ndGggPSBzcXJ0KGxlbmd0aCk7CiAgICBuWzBdID0gblswXSAvIGxlbmd0aDsKICAgIG5bMV0gPSBuWzFdIC8gbGVuZ3RoOwogICAgblsyXSA9IG5bMl0gLyBsZW5ndGg7Cn0KCi8qIFRlc3NlbGF0ZXMgYSBoaWdoIG9yZGVyIHJlY3Rhbmd1bGFyIHBhdGNoIGludG8gc2luZ2xlIHRyaWFuZ2xlcyB1c2luZyBnbCBldmFsdWF0b3JzCiAqCiAqIFRoZSBwcm9ibGVtIGlzIHRoYXQgT3BlbkdMIGRvZXMgbm90IG9mZmVyIGEgZGlyZWN0IHdheSB0byByZXR1cm4gdGhlIHRlc3NlbGF0ZWQgcHJpbWl0aXZlcywKICogYW5kIHRoZXkgY2FuJ3QgYmUgc2VudCBvZmYgZm9yIHJlbmRlcmluZyBkaXJlY3RseSBlaXRoZXIuIFRlc3NlbGF0aW5nIGlzIHNsb3csIHNvIHdlIHdhbnQKICogdG8gY2hhY2hlIHRoZSBwYXRjaGVzIGluIGEgdmVydGV4IGJ1ZmZlci4gQnV0IG1vcmUgaW1wb3J0YW50bHksIGdsIGNhbid0IGJpbmQgZ2VuZXJhdGVkCiAqIGF0dHJpYnV0ZXMgdG8gbnVtYmVyZWQgc2hhZGVyIGF0dHJpYnV0ZXMsIHNvIHdlIGhhdmUgdG8gc3RvcmUgdGhlbSBhbmQgcmViaW5kIHRoZW0gYXMgbmVlZGVkCiAqIGluIGRyYXdwcmltLgogKgogKiBUbyByZWFkIGJhY2ssIHRoZSBvcGVuZ2wgZmVlZGJhY2sgbW9kZSBpcyB1c2VkLiBUaGlzIGNyZWF0ZXMgYSBwcm9wbGVtIGJlY2F1c2Ugd2Ugd2FudAogKiB1bnRyYW5zZm9ybWVkLCB1bmxpdCB2ZXJ0aWNlcywgYnV0IGZlZWRiYWNrIHJ1bnMgZXZlcnl0aGluZyB0aHJvdWdoIHRyYW5zZm9ybSBhbmQgbGlnaHRpbmcuCiAqIFRodXMgZGlzYWJsZSBsaWdodGluZyBhbmQgc2V0IGlkZW50aXR5IG1hdHJpY2VzIHRvIGdldCB1bm1vZGlmaWVkIGNvbG9ycyBhbmQgcG9zaXRpb25zLgogKiBUbyBvdmVyY29tZSBjbGlwcGluZyBmaW5kIHRoZSBiaWdnZXN0IHgsIHkgYW5kIHogdmFsdWVzIG9mIHRoZSB2ZXJ0aWNlcyBpbiB0aGUgcGF0Y2ggYW5kIHNjYWxlCiAqIHRoZW0gdG8gWy0xLjA7KzEuMF0gYW5kIHNldCB0aGUgdmlld3BvcnQgdXAgdG8gc2NhbGUgdGhlbSBiYWNrLgogKgogKiBOb3JtYWxzIGFyZSBtb3JlIHRyaWNreTogRHJhdyB3aGl0ZSB2ZXJ0aWNlcyB3aXRoIDMgZGlyZWN0aW9uYWwgbGlnaHRzLCBhbmQgY2FsY3VsYXRlIHRoZQogKiByZXN1bHRpbmcgY29sb3JzIGJhY2sgdG8gdGhlIG5vcm1hbHMuCiAqCiAqIE5PVEU6IFRoaXMgZnVuY3Rpb24gYWN0aXZhdGVzIGEgY29udGV4dCBmb3IgYmxpdHRpbmcsIG1vZGlmaWVzIG1hdHJpY2VzICYgdmlld3BvcnQsIGJ1dAogKiBkb2VzIG5vdCByZXN0b3JlIGl0IGJlY2F1c2Ugbm9ybWFsbHkgYSBkcmF3IGZvbGxvd3MgaW1tZWRpYXRlbHkgYWZ0ZXJ3YXJkcy4gVGhlIGNhbGxlciBpcwogKiByZXNwb25zaWJsZSBvZiB0YWtpbmcgY2FyZSB0aGF0IGVpdGhlciB0aGUgZ2wgc3RhdGVzIGFyZSByZXN0b3JlZCwgb3IgdGhlIGNvbnRleHQgYWN0aXZhdGVkCiAqIGZvciBkcmF3aW5nIHRvIHJlc2V0IHRoZSBsYXN0V2FzQmxpdCBmbGFnLgogKi8KSFJFU1VMVCB0ZXNzZWxhdGVfcmVjdHBhdGNoKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBXaW5lRDNEUmVjdFBhdGNoICpwYXRjaCkgewogICAgdW5zaWduZWQgaW50IGksIGosIG51bV9xdWFkcywgb3V0X3ZlcnRleF9zaXplLCBidWZmZXJfc2l6ZSwgZDNkX291dF92ZXJ0ZXhfc2l6ZTsKICAgIGZsb2F0IG1heF94ID0gMC4wLCBtYXhfeSA9IDAuMCwgbWF4X3ogPSAwLjAsIG5lZ196ID0gMC4wOwogICAgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgc3RyaWRlZDsKICAgIEJZVEUgKmRhdGE7CiAgICBXSU5FRDNEUkVDVFBBVENIX0lORk8gKmluZm8gPSAmcGF0Y2gtPlJlY3RQYXRjaEluZm87CiAgICBEV09SRCB2dHhTdHJpZGU7CiAgICBHTGVudW0gZmVlZGJhY2tfdHlwZTsKICAgIEdMZmxvYXQgKmZlZWRidWZmZXI7CgogICAgLyogRmlyc3QsIGxvY2F0ZSB0aGUgcG9zaXRpb24gZGF0YS4gVGhpcyBpcyBwcm92aWRlZCBpbiBhIHZlcnRleCBidWZmZXIgaW4gdGhlIHN0YXRlYmxvY2suCiAgICAgKiBCZXdhcmUgb2YgdmJvcwogICAgICovCiAgICBtZW1zZXQoJnN0cmlkZWQsIDAsIHNpemVvZihzdHJpZGVkKSk7CiAgICBwcmltaXRpdmVEZWNsYXJhdGlvbkNvbnZlcnRUb1N0cmlkZWREYXRhKChJV2luZUQzRERldmljZSAqKSBUaGlzLCBGQUxTRSwgJnN0cmlkZWQsIE5VTEwpOwogICAgaWYoc3RyaWRlZC51LnMucG9zaXRpb24uVkJPKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICp2YjsKICAgICAgICB2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmlkZWQudS5zLnBvc2l0aW9uLnN0cmVhbU5vXTsKICAgICAgICBzdHJpZGVkLnUucy5wb3NpdGlvbi5scERhdGEgPSAoQllURSAqKSAoKHVuc2lnbmVkIGxvbmcpIHN0cmlkZWQudS5zLnBvc2l0aW9uLmxwRGF0YSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKSB2Yi0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIH0KICAgIHZ0eFN0cmlkZSA9IHN0cmlkZWQudS5zLnBvc2l0aW9uLmR3U3RyaWRlOwogICAgZGF0YSA9IHN0cmlkZWQudS5zLnBvc2l0aW9uLmxwRGF0YSArCiAgICAgICAgICAgdnR4U3RyaWRlICogaW5mby0+U3RyaWRlICogaW5mby0+U3RhcnRWZXJ0ZXhPZmZzZXRIZWlnaHQgKwogICAgICAgICAgIHZ0eFN0cmlkZSAqIGluZm8tPlN0YXJ0VmVydGV4T2Zmc2V0V2lkdGg7CgogICAgLyogTm90IGVudGlyZWx5IHN1cmUgYWJvdXQgd2hhdCBoYXBwZW5zIHdpdGggdHJhbnNmb3JtZWQgdmVydGljZXMgKi8KICAgIGlmKHN0cmlkZWQudS5zLnBvc2l0aW9uX3RyYW5zZm9ybWVkKSB7CiAgICAgICAgRklYTUUoIlRyYW5zZm9ybWVkIHBvc2l0aW9uIGluIHJlY3RwYXRjaCBnZW5lcmF0aW9uXG4iKTsKICAgIH0KICAgIGlmKHZ0eFN0cmlkZSAlIHNpemVvZihHTGZsb2F0KSkgewogICAgICAgIC8qIGdsTWFwMmYgcmVhZHMgdmVydGV4IHNpemVzIGluIEdMZmxvYXRzLCB0aGUgZDNkIHN0cmlkZSBpcyBpbiBieXRlcy4KICAgICAgICAgKiBJIGRvbid0IHNlZSBob3cgdGhlIHN0cmlkZSBjb3VsZCBub3QgYmUgYSBtdWx0aXBsZSBvZiA0LCBidXQgbWFrZSBzdXJlCiAgICAgICAgICogdG8gY2hlY2sgaXQKICAgICAgICAgKi8KICAgICAgICBFUlIoIlZlcnRleCBzdHJpZGUgaXMgbm90IGEgbXVsdGlwbGUgb2Ygc2l6ZW9mKEdMZmxvYXQpXG4iKTsKICAgIH0KICAgIGlmKGluZm8tPkJhc2lzICE9IFdJTkVEM0RCQVNJU19CRVpJRVIpIHsKICAgICAgICBGSVhNRSgiQmFzaXMgaXMgJXMsIGhvdyB0byBoYW5kbGUgdGhpcz9cbiIsIGRlYnVnX2QzZGJhc2lzKGluZm8tPkJhc2lzKSk7CiAgICB9CiAgICBpZihpbmZvLT5EZWdyZWUgIT0gV0lORUQzRERFR1JFRV9DVUJJQykgewogICAgICAgIEZJWE1FKCJEZWdyZWUgaXMgJXMsIGhvdyB0byBoYW5kbGUgdGhpcz9cbiIsIGRlYnVnX2QzZGRlZ3JlZShpbmZvLT5EZWdyZWUpKTsKICAgIH0KCiAgICAvKiBGaXJzdCwgZ2V0IHRoZSBib3VuZGFyeSBjdWJlIG9mIHRoZSBpbnB1dCBkYXRhICovCiAgICBmb3IoaiA9IDA7IGogPCBpbmZvLT5IZWlnaHQ7IGorKykgewogICAgICAgIGZvcihpID0gMDsgaSA8IGluZm8tPldpZHRoOyBpKyspIHsKICAgICAgICAgICAgZmxvYXQgKnYgPSAoZmxvYXQgKikgKGRhdGEgKyB2dHhTdHJpZGUgKiBpICsgdnR4U3RyaWRlICogaW5mby0+U3RyaWRlICogaik7CiAgICAgICAgICAgIGlmKGZhYnModlswXSkgPiBtYXhfeCkgbWF4X3ggPSBmYWJzKHZbMF0pOwogICAgICAgICAgICBpZihmYWJzKHZbMV0pID4gbWF4X3kpIG1heF95ID0gZmFicyh2WzFdKTsKICAgICAgICAgICAgaWYoZmFicyh2WzJdKSA+IG1heF96KSBtYXhfeiA9IGZhYnModlsyXSk7CiAgICAgICAgICAgIGlmKHZbMl0gPCBuZWdfeikgbmVnX3ogPSB2WzJdOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBUaGlzIG5lZWRzIHNvbWUgaW1wcm92ZW1lbnRzIGluIHRoZSB2ZXJ0ZXggZGVjbCBjb2RlICovCiAgICBGSVhNRSgiQ2Fubm90IGZpbmQgZGF0YSB0byBnZW5lcmF0ZS4gT25seSBnZW5lcmF0aW5nIHBvc2l0aW9uIGFuZCBub3JtYWxzXG4iKTsKICAgIHBhdGNoLT5oYXNfbm9ybWFscyA9IFRSVUU7CiAgICBwYXRjaC0+aGFzX3RleGNvb3JkcyA9IEZBTFNFOwoKICAgIC8qIFNpbXBseSBhY3RpdmF0ZSB0aGUgY29udGV4dCBmb3IgYmxpdHRpbmcuIFRoaXMgZGlzYWJsZXMgYWxsIHRoZSB0aGluZ3Mgd2UgZG9uJ3Qgd2FudCBhbmQKICAgICAqIHRha2VzIGNhcmUgb2YgZGlydGlmeWluZy4gRGlydGlmeWluZyBpcyBwcmVmZXJyZWQgb3ZlciBwdXNoaW5nIC8gcG9wcGluZywgc2luY2UgZHJhd2luZyB0aGUKICAgICAqIHBhdGNoIChhcyBvcHBvc2VkIHRvIG5vcm1hbCBkcmF3cykgd2lsbCBtb3N0IGxpa2VseSBuZWVkIGRpZmZlcmVudCBjaGFuZ2VzIGFueXdheQogICAgICovCiAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfQkxJVCk7CiAgICBFTlRFUl9HTCgpOwoKICAgIGdsTWF0cml4TW9kZShHTF9QUk9KRUNUSU9OKTsKICAgIGNoZWNrR0xjYWxsKCJnbE1hdHJpeE1vZGUoR0xfUFJPSkVDVElPTikiKTsKICAgIGdsTG9hZElkZW50aXR5KCk7CiAgICBjaGVja0dMY2FsbCgiZ2xMb2FkSW5kZW50aXR5KCkiKTsKICAgIGdsU2NhbGVmKDEgLyAobWF4X3gpICwgMSAvIChtYXhfeSksIG1heF96ID09IDAgPyAxIDogMSAvICggMiAqIG1heF96KSk7CiAgICBnbFRyYW5zbGF0ZWYoMCwgMCwgMC41KTsKICAgIGNoZWNrR0xjYWxsKCJnbFNjYWxlZiIpOwogICAgZ2xWaWV3cG9ydCgtbWF4X3gsIC1tYXhfeSwgMiAqIChtYXhfeCksIDIgKiAobWF4X3kpKTsKICAgIGNoZWNrR0xjYWxsKCJnbFZpZXdwb3J0Iik7CgogICAgLyogU29tZSBzdGF0ZXMgdG8gdGFrZSBjYXJlIG9mLiBJZiB3ZSdyZSBpbiB3aXJlZnJhbWUgb3BlbmdsIHdpbGwgcHJvZHVjZSBsaW5lcywgYW5kIGNvbmZ1c2UKICAgICAqIG91ciBmZWVkYmFjayBidWZmZXIgcGFyc2VyCiAgICAgKi8KICAgIGdsUG9seWdvbk1vZGUoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX0ZJTEwpOwogICAgY2hlY2tHTGNhbGwoImdsUG9seWdvbk1vZGUoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX0ZJTEwpIik7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19GSUxMTU9ERSkpOwogICAgaWYocGF0Y2gtPmhhc19ub3JtYWxzKSB7CiAgICAgICAgZmxvYXQgYmxhY2tbNF0gPSB7MCwgMCwgMCwgMH07CiAgICAgICAgZmxvYXQgcmVkWzRdICAgPSB7MSwgMCwgMCwgMH07CiAgICAgICAgZmxvYXQgZ3JlZW5bNF0gPSB7MCwgMSwgMCwgMH07CiAgICAgICAgZmxvYXQgYmx1ZVs0XSAgPSB7MCwgMCwgMSwgMH07CiAgICAgICAgZmxvYXQgd2hpdGVbNF0gPSB7MSwgMSwgMSwgMX07CiAgICAgICAgZ2xFbmFibGUoR0xfTElHSFRJTkcpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9MSUdIVElORykiKTsKICAgICAgICBnbExpZ2h0TW9kZWxmdihHTF9MSUdIVF9NT0RFTF9BTUJJRU5ULCBibGFjayk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsTGlnaHRNb2RlbCBmb3IgTU9ERUxfQU1CSUVOVCIpOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0FNQklFTlQpKTsKCiAgICAgICAgZm9yKGkgPSAzOyBpIDwgR0xfTElNSVRTKGxpZ2h0cyk7IGkrKykgewogICAgICAgICAgICBnbERpc2FibGUoR0xfTElHSFQwICsgaSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfTElHSFQwICsgaSkiKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0FDVElWRUxJR0hUKGkpKTsKICAgICAgICB9CgogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9BQ1RJVkVMSUdIVCgwKSk7CiAgICAgICAgZ2xMaWdodGZ2KEdMX0xJR0hUMCwgR0xfRElGRlVTRSwgcmVkKTsKICAgICAgICBnbExpZ2h0ZnYoR0xfTElHSFQwLCBHTF9TUEVDVUxBUiwgYmxhY2spOwogICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDAsIEdMX0FNQklFTlQsIGJsYWNrKTsKICAgICAgICBnbExpZ2h0ZnYoR0xfTElHSFQwLCBHTF9QT1NJVElPTiwgcmVkKTsKICAgICAgICBnbEVuYWJsZShHTF9MSUdIVDApOwogICAgICAgIGNoZWNrR0xjYWxsKCJTZXR0aW5nIHVwIGxpZ2h0IDFcbiIpOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9BQ1RJVkVMSUdIVCgxKSk7CiAgICAgICAgZ2xMaWdodGZ2KEdMX0xJR0hUMSwgR0xfRElGRlVTRSwgZ3JlZW4pOwogICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDEsIEdMX1NQRUNVTEFSLCBibGFjayk7CiAgICAgICAgZ2xMaWdodGZ2KEdMX0xJR0hUMSwgR0xfQU1CSUVOVCwgYmxhY2spOwogICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDEsIEdMX1BPU0lUSU9OLCBncmVlbik7CiAgICAgICAgZ2xFbmFibGUoR0xfTElHSFQxKTsKICAgICAgICBjaGVja0dMY2FsbCgiU2V0dGluZyB1cCBsaWdodCAyXG4iKTsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfQUNUSVZFTElHSFQoMikpOwogICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDIsIEdMX0RJRkZVU0UsIGJsdWUpOwogICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDIsIEdMX1NQRUNVTEFSLCBibGFjayk7CiAgICAgICAgZ2xMaWdodGZ2KEdMX0xJR0hUMiwgR0xfQU1CSUVOVCwgYmxhY2spOwogICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDIsIEdMX1BPU0lUSU9OLCBibHVlKTsKICAgICAgICBnbEVuYWJsZShHTF9MSUdIVDIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJTZXR0aW5nIHVwIGxpZ2h0IDNcbiIpOwoKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfTUFURVJJQUwpOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0NPTE9SVkVSVEVYKSk7CiAgICAgICAgZ2xEaXNhYmxlKEdMX0NPTE9SX01BVEVSSUFMKTsKICAgICAgICBnbE1hdGVyaWFsZnYoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX0VNSVNTSU9OLCBibGFjayk7CiAgICAgICAgZ2xNYXRlcmlhbGZ2KEdMX0ZST05UX0FORF9CQUNLLCBHTF9TUEVDVUxBUiwgYmxhY2spOwogICAgICAgIGdsTWF0ZXJpYWxmdihHTF9GUk9OVF9BTkRfQkFDSywgR0xfRElGRlVTRSwgd2hpdGUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJTZXR0aW5nIHVwIG1hdGVyaWFsc1xuIik7CiAgICB9CgogICAgLyogRW5hYmxlIHRoZSBuZWVkZWQgbWFwcy4KICAgICAqIEdMX01BUDJfVkVSVEVYXzMgaXMgbmVlZGVkIGZvciBwb3NpdGlvbmFsIGRhdGEuCiAgICAgKiBHTF9BVVRPX05PUk1BTCB0byBnZW5lcmF0ZSBub3JtYWxzIGZyb20gdGhlIHBvc2l0aW9uLiBEbyBub3QgdXNlIEdMX01BUDJfTk9STUFMLgogICAgICogR0xfTUFQMl9URVhUVVJFX0NPT1JEXzQgZm9yIHRleHR1cmUgY29vcmRzCiAgICAgKi8KICAgIG51bV9xdWFkcyA9IGNlaWxmKHBhdGNoLT5udW1TZWdzWzBdKSAqIGNlaWxmKHBhdGNoLT5udW1TZWdzWzFdKTsKICAgIG91dF92ZXJ0ZXhfc2l6ZSA9IDMgLyogcG9zaXRpb24gKi87CiAgICBkM2Rfb3V0X3ZlcnRleF9zaXplID0gMzsKICAgIGdsRW5hYmxlKEdMX01BUDJfVkVSVEVYXzMpOwogICAgaWYocGF0Y2gtPmhhc19ub3JtYWxzICYmIHBhdGNoLT5oYXNfdGV4Y29vcmRzKSB7CiAgICAgICAgRklYTUUoIlRleGNvb3JkcyBub3QgaGFuZGxlZCB5ZXRcbiIpOwogICAgICAgIGZlZWRiYWNrX3R5cGUgPSBHTF8zRF9DT0xPUl9URVhUVVJFOwogICAgICAgIG91dF92ZXJ0ZXhfc2l6ZSArPSA4OwogICAgICAgIGQzZF9vdXRfdmVydGV4X3NpemUgKz0gNzsKICAgICAgICBnbEVuYWJsZShHTF9BVVRPX05PUk1BTCk7CiAgICAgICAgZ2xFbmFibGUoR0xfTUFQMl9URVhUVVJFX0NPT1JEXzQpOwogICAgfSBlbHNlIGlmKHBhdGNoLT5oYXNfdGV4Y29vcmRzKSB7CiAgICAgICAgRklYTUUoIlRleGNvb3JkcyBub3QgaGFuZGxlZCB5ZXRcbiIpOwogICAgICAgIGZlZWRiYWNrX3R5cGUgPSBHTF8zRF9DT0xPUl9URVhUVVJFOwogICAgICAgIG91dF92ZXJ0ZXhfc2l6ZSArPSA3OwogICAgICAgIGQzZF9vdXRfdmVydGV4X3NpemUgKz0gNDsKICAgICAgICBnbEVuYWJsZShHTF9NQVAyX1RFWFRVUkVfQ09PUkRfNCk7CiAgICB9IGVsc2UgaWYocGF0Y2gtPmhhc19ub3JtYWxzKSB7CiAgICAgICAgZmVlZGJhY2tfdHlwZSA9IEdMXzNEX0NPTE9SOwogICAgICAgIG91dF92ZXJ0ZXhfc2l6ZSArPSA0OwogICAgICAgIGQzZF9vdXRfdmVydGV4X3NpemUgKz0gMzsKICAgICAgICBnbEVuYWJsZShHTF9BVVRPX05PUk1BTCk7CiAgICB9IGVsc2UgewogICAgICAgIGZlZWRiYWNrX3R5cGUgPSBHTF8zRDsKICAgIH0KICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSB2ZXJ0ZXggYXR0cmliIGdlbmVyYXRpb24iKTsKCiAgICBidWZmZXJfc2l6ZSA9IG51bV9xdWFkcyAqIG91dF92ZXJ0ZXhfc2l6ZSAqIDIgLyogdHJpYW5nbGUgbGlzdCAqLyAqIDMgLyogdmVydHMgcGVyIHRyaSAqLwogICAgICAgICAgICAgICAgICAgKyA0ICogbnVtX3F1YWRzIC8qIDIgdHJpYW5nbGUgbWFya2VycyBwZXIgcXVhZCArIG51bSB2ZXJ0cyBpbiB0cmkgKi87CiAgICBmZWVkYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGJ1ZmZlcl9zaXplICogc2l6ZW9mKGZsb2F0KSAqIDgpOwoKICAgIGdsTWFwMmYoR0xfTUFQMl9WRVJURVhfMywKICAgICAgICAgICAgMCwgMSwgdnR4U3RyaWRlIC8gc2l6ZW9mKGZsb2F0KSwgaW5mby0+V2lkdGgsCiAgICAgICAgICAgIDAsIDEsIGluZm8tPlN0cmlkZSAqIHZ0eFN0cmlkZSAvIHNpemVvZihmbG9hdCksIGluZm8tPkhlaWdodCwKICAgICAgICAgICAgKGZsb2F0ICopIGRhdGEpOwogICAgY2hlY2tHTGNhbGwoImdsTWFwMmYiKTsKICAgIGlmKHBhdGNoLT5oYXNfdGV4Y29vcmRzKSB7CiAgICAgICAgZ2xNYXAyZihHTF9NQVAyX1RFWFRVUkVfQ09PUkRfNCwKICAgICAgICAgICAgICAgIDAsIDEsIHZ0eFN0cmlkZSAvIHNpemVvZihmbG9hdCksIGluZm8tPldpZHRoLAogICAgICAgICAgICAgICAgMCwgMSwgaW5mby0+U3RyaWRlICogdnR4U3RyaWRlIC8gc2l6ZW9mKGZsb2F0KSwgaW5mby0+SGVpZ2h0LAogICAgICAgICAgICAgICAgKGZsb2F0ICopIGRhdGEpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbE1hcDJmIik7CiAgICB9CiAgICBnbE1hcEdyaWQyZihjZWlsZihwYXRjaC0+bnVtU2Vnc1swXSksIDAuMCwgMS4wLCBjZWlsZihwYXRjaC0+bnVtU2Vnc1sxXSksIDAuMCwgMS4wKTsKICAgIGNoZWNrR0xjYWxsKCJnbE1hcEdyaWQyZiIpOwoKICAgIGdsRmVlZGJhY2tCdWZmZXIoYnVmZmVyX3NpemUgKiAyLCBmZWVkYmFja190eXBlLCBmZWVkYnVmZmVyKTsKICAgIGNoZWNrR0xjYWxsKCJnbEZlZWRiYWNrQnVmZmVyIik7CiAgICBnbFJlbmRlck1vZGUoR0xfRkVFREJBQ0spOwoKICAgIGdsRXZhbE1lc2gyKEdMX0ZJTEwsIDAsIGNlaWxmKHBhdGNoLT5udW1TZWdzWzBdKSwgMCwgY2VpbGYocGF0Y2gtPm51bVNlZ3NbMV0pKTsKICAgIGNoZWNrR0xjYWxsKCJnbEV2YWxNZXNoMlxuIik7CgogICAgaSA9IGdsUmVuZGVyTW9kZShHTF9SRU5ERVIpOwogICAgaWYoaSA9PSAtMSkgewogICAgICAgIEVSUigiRmVlZGJhY2sgZmFpbGVkLiBFeHBlY3RlZCAlZCBlbGVtZW50cyBiYWNrXG4iLCBidWZmZXJfc2l6ZSk7CiAgICAgICAgU2xlZXAoMTAwMDApOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGZlZWRidWZmZXIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0RSSVZFUklOVEVSTkFMRVJST1I7CiAgICB9IGVsc2UgaWYoaSAhPSBidWZmZXJfc2l6ZSkgewogICAgICAgIEVSUigiVW5leHBlY3RlZCBhbW91bnQgb2YgZWxlbWVudHMgcmV0dXJuZWQuIEV4cGVjdGVkICVkLCBnb3QgJWRcbiIsIGJ1ZmZlcl9zaXplLCBpKTsKICAgICAgICBTbGVlcCgxMDAwMCk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZmVlZGJ1ZmZlcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfRFJJVkVSSU5URVJOQUxFUlJPUjsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIkdvdCAlZCBlbGVtZW50cyBhcyBleHBlY3RlZFxuIiwgaSk7CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGF0Y2gtPm1lbSk7CiAgICBwYXRjaC0+bWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIG51bV9xdWFkcyAqIDYgKiBkM2Rfb3V0X3ZlcnRleF9zaXplICogc2l6ZW9mKGZsb2F0KSAqIDgpOwogICAgaSA9IDA7CiAgICBmb3IoaiA9IDA7IGogPCBidWZmZXJfc2l6ZTsgaiArPSAoMyAvKiBudW0gdmVydHMgKi8gKiBvdXRfdmVydGV4X3NpemUgKyAyIC8qIHRyaSBtYXJrZXIgKi8pKSB7CiAgICAgICAgaWYoZmVlZGJ1ZmZlcltqXSAhPSBHTF9QT0xZR09OX1RPS0VOKSB7CiAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCB0b2tlbjogJWZcbiIsIGZlZWRidWZmZXJbal0pOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYoZmVlZGJ1ZmZlcltqICsgMV0gIT0gMykgewogICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgcG9seWdvbjogJWYgY29ybmVyc1xuIiwgZmVlZGJ1ZmZlcltqICsgMV0pOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgLyogU29tZWhvdyB0aGVyZSBhcmUgZGlmZmVyZW50IGlkZWFzIGFib3V0IGJhY2sgLyBmcm9udCBmYWNpbmcsIHNvIGZpeCB1cCB0aGUKICAgICAgICAgKiB2ZXJ0ZXggb3JkZXIKICAgICAgICAgKi8KICAgICAgICBwYXRjaC0+bWVtW2kgKyAwXSA9ICBmZWVkYnVmZmVyW2ogKyBvdXRfdmVydGV4X3NpemUgKiAyICsgMl07IC8qIHgsIHRyaWFuZ2xlIDIgKi8KICAgICAgICBwYXRjaC0+bWVtW2kgKyAxXSA9ICBmZWVkYnVmZmVyW2ogKyBvdXRfdmVydGV4X3NpemUgKiAyICsgM107IC8qIHksIHRyaWFuZ2xlIDIgKi8KICAgICAgICBwYXRjaC0+bWVtW2kgKyAyXSA9IChmZWVkYnVmZmVyW2ogKyBvdXRfdmVydGV4X3NpemUgKiAyICsgNF0gLSAwLjUpICogNCAqIG1heF96OyAvKiB6LCB0cmlhbmdsZSAzICovCiAgICAgICAgaWYocGF0Y2gtPmhhc19ub3JtYWxzKSB7CiAgICAgICAgICAgIHBhdGNoLT5tZW1baSArIDNdID0gZmVlZGJ1ZmZlcltqICsgb3V0X3ZlcnRleF9zaXplICogMiArIDVdOwogICAgICAgICAgICBwYXRjaC0+bWVtW2kgKyA0XSA9IGZlZWRidWZmZXJbaiArIG91dF92ZXJ0ZXhfc2l6ZSAqIDIgKyA2XTsKICAgICAgICAgICAgcGF0Y2gtPm1lbVtpICsgNV0gPSBmZWVkYnVmZmVyW2ogKyBvdXRfdmVydGV4X3NpemUgKiAyICsgN107CiAgICAgICAgfQogICAgICAgIGkgKz0gZDNkX291dF92ZXJ0ZXhfc2l6ZTsKCiAgICAgICAgcGF0Y2gtPm1lbVtpICsgMF0gPSAgZmVlZGJ1ZmZlcltqICsgb3V0X3ZlcnRleF9zaXplICogMSArIDJdOyAvKiB4LCB0cmlhbmdsZSAyICovCiAgICAgICAgcGF0Y2gtPm1lbVtpICsgMV0gPSAgZmVlZGJ1ZmZlcltqICsgb3V0X3ZlcnRleF9zaXplICogMSArIDNdOyAvKiB5LCB0cmlhbmdsZSAyICovCiAgICAgICAgcGF0Y2gtPm1lbVtpICsgMl0gPSAoZmVlZGJ1ZmZlcltqICsgb3V0X3ZlcnRleF9zaXplICogMSArIDRdIC0gMC41KSAqIDQgKiBtYXhfejsgLyogeiwgdHJpYW5nbGUgMiAqLwogICAgICAgIGlmKHBhdGNoLT5oYXNfbm9ybWFscykgewogICAgICAgICAgICBwYXRjaC0+bWVtW2kgKyAzXSA9IGZlZWRidWZmZXJbaiArIG91dF92ZXJ0ZXhfc2l6ZSAqIDEgKyA1XTsKICAgICAgICAgICAgcGF0Y2gtPm1lbVtpICsgNF0gPSBmZWVkYnVmZmVyW2ogKyBvdXRfdmVydGV4X3NpemUgKiAxICsgNl07CiAgICAgICAgICAgIHBhdGNoLT5tZW1baSArIDVdID0gZmVlZGJ1ZmZlcltqICsgb3V0X3ZlcnRleF9zaXplICogMSArIDddOwogICAgICAgIH0KICAgICAgICBpICs9IGQzZF9vdXRfdmVydGV4X3NpemU7CgogICAgICAgIHBhdGNoLT5tZW1baSArIDBdID0gIGZlZWRidWZmZXJbaiArIG91dF92ZXJ0ZXhfc2l6ZSAqIDAgKyAyXTsgLyogeCwgdHJpYW5nbGUgMSAqLwogICAgICAgIHBhdGNoLT5tZW1baSArIDFdID0gIGZlZWRidWZmZXJbaiArIG91dF92ZXJ0ZXhfc2l6ZSAqIDAgKyAzXTsgLyogeSwgdHJpYW5nbGUgMSAqLwogICAgICAgIHBhdGNoLT5tZW1baSArIDJdID0gKGZlZWRidWZmZXJbaiArIG91dF92ZXJ0ZXhfc2l6ZSAqIDAgKyA0XSAtIDAuNSkgKiA0ICogbWF4X3o7IC8qIHosIHRyaWFuZ2xlIDEgKi8KICAgICAgICBpZihwYXRjaC0+aGFzX25vcm1hbHMpIHsKICAgICAgICAgICAgcGF0Y2gtPm1lbVtpICsgM10gPSBmZWVkYnVmZmVyW2ogKyBvdXRfdmVydGV4X3NpemUgKiAwICsgNV07CiAgICAgICAgICAgIHBhdGNoLT5tZW1baSArIDRdID0gZmVlZGJ1ZmZlcltqICsgb3V0X3ZlcnRleF9zaXplICogMCArIDZdOwogICAgICAgICAgICBwYXRjaC0+bWVtW2kgKyA1XSA9IGZlZWRidWZmZXJbaiArIG91dF92ZXJ0ZXhfc2l6ZSAqIDAgKyA3XTsKICAgICAgICB9CiAgICAgICAgaSArPSBkM2Rfb3V0X3ZlcnRleF9zaXplOwogICAgfQoKICAgIGlmKHBhdGNoLT5oYXNfbm9ybWFscykgewogICAgICAgIC8qIE5vdyBkbyB0aGUgc2FtZSB3aXRoIHJldmVyc2UgbGlnaHQgZGlyZWN0aW9ucyAqLwogICAgICAgIGZsb2F0IHhbNF0gPSB7LTEsICAwLCAgMCwgMH07CiAgICAgICAgZmxvYXQgeVs0XSA9IHsgMCwgLTEsICAwLCAwfTsKICAgICAgICBmbG9hdCB6WzRdID0geyAwLCAgMCwgLTEsIDB9OwogICAgICAgIGdsTGlnaHRmdihHTF9MSUdIVDAsIEdMX1BPU0lUSU9OLCB4KTsKICAgICAgICBnbExpZ2h0ZnYoR0xfTElHSFQxLCBHTF9QT1NJVElPTiwgeSk7CiAgICAgICAgZ2xMaWdodGZ2KEdMX0xJR0hUMiwgR0xfUE9TSVRJT04sIHopOwogICAgICAgIGNoZWNrR0xjYWxsKCJTZXR0aW5nIHVwIHJldmVyc2UgbGlnaHQgZGlyZWN0aW9uc1xuIik7CgogICAgICAgIGdsUmVuZGVyTW9kZShHTF9GRUVEQkFDSyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVuZGVyTW9kZShHTF9GRUVEQkFDSykiKTsKICAgICAgICBnbEV2YWxNZXNoMihHTF9GSUxMLCAwLCBjZWlsZihwYXRjaC0+bnVtU2Vnc1swXSksIDAsIGNlaWxmKHBhdGNoLT5udW1TZWdzWzFdKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRXZhbE1lc2gyXG4iKTsKICAgICAgICBpID0gZ2xSZW5kZXJNb2RlKEdMX1JFTkRFUik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVuZGVyTW9kZShHTF9SRU5ERVIpIik7CgogICAgICAgIGkgPSAwOwogICAgICAgIGZvcihqID0gMDsgaiA8IGJ1ZmZlcl9zaXplOyBqICs9ICgzIC8qIG51bSB2ZXJ0cyAqLyAqIG91dF92ZXJ0ZXhfc2l6ZSArIDIgLyogdHJpIG1hcmtlciAqLykpIHsKICAgICAgICAgICAgaWYoZmVlZGJ1ZmZlcltqXSAhPSBHTF9QT0xZR09OX1RPS0VOKSB7CiAgICAgICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgdG9rZW46ICVmXG4iLCBmZWVkYnVmZmVyW2pdKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGZlZWRidWZmZXJbaiArIDFdICE9IDMpIHsKICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBwb2x5Z29uOiAlZiBjb3JuZXJzXG4iLCBmZWVkYnVmZmVyW2ogKyAxXSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihwYXRjaC0+bWVtW2kgKyAzXSA9PSAwLjApCiAgICAgICAgICAgICAgICBwYXRjaC0+bWVtW2kgKyAzXSA9IC1mZWVkYnVmZmVyW2ogKyBvdXRfdmVydGV4X3NpemUgKiAyICsgNV07CiAgICAgICAgICAgIGlmKHBhdGNoLT5tZW1baSArIDRdID09IDAuMCkKICAgICAgICAgICAgICAgIHBhdGNoLT5tZW1baSArIDRdID0gLWZlZWRidWZmZXJbaiArIG91dF92ZXJ0ZXhfc2l6ZSAqIDIgKyA2XTsKICAgICAgICAgICAgaWYocGF0Y2gtPm1lbVtpICsgNV0gPT0gMC4wKQogICAgICAgICAgICAgICAgcGF0Y2gtPm1lbVtpICsgNV0gPSAtZmVlZGJ1ZmZlcltqICsgb3V0X3ZlcnRleF9zaXplICogMiArIDddOwogICAgICAgICAgICBub3JtYWxpemVfbm9ybWFsKHBhdGNoLT5tZW0gKyBpICsgMyk7CiAgICAgICAgICAgIGkgKz0gZDNkX291dF92ZXJ0ZXhfc2l6ZTsKCiAgICAgICAgICAgIGlmKHBhdGNoLT5tZW1baSArIDNdID09IDAuMCkKICAgICAgICAgICAgICAgIHBhdGNoLT5tZW1baSArIDNdID0gLWZlZWRidWZmZXJbaiArIG91dF92ZXJ0ZXhfc2l6ZSAqIDEgKyA1XTsKICAgICAgICAgICAgaWYocGF0Y2gtPm1lbVtpICsgNF0gPT0gMC4wKQogICAgICAgICAgICAgICAgcGF0Y2gtPm1lbVtpICsgNF0gPSAtZmVlZGJ1ZmZlcltqICsgb3V0X3ZlcnRleF9zaXplICogMSArIDZdOwogICAgICAgICAgICBpZihwYXRjaC0+bWVtW2kgKyA1XSA9PSAwLjApCiAgICAgICAgICAgICAgICBwYXRjaC0+bWVtW2kgKyA1XSA9IC1mZWVkYnVmZmVyW2ogKyBvdXRfdmVydGV4X3NpemUgKiAxICsgN107CiAgICAgICAgICAgIG5vcm1hbGl6ZV9ub3JtYWwocGF0Y2gtPm1lbSArIGkgKyAzKTsKICAgICAgICAgICAgaSArPSBkM2Rfb3V0X3ZlcnRleF9zaXplOwoKICAgICAgICAgICAgaWYocGF0Y2gtPm1lbVtpICsgM10gPT0gMC4wKQogICAgICAgICAgICAgICAgcGF0Y2gtPm1lbVtpICsgM10gPSAtZmVlZGJ1ZmZlcltqICsgb3V0X3ZlcnRleF9zaXplICogMCArIDVdOwogICAgICAgICAgICBpZihwYXRjaC0+bWVtW2kgKyA0XSA9PSAwLjApCiAgICAgICAgICAgICAgICBwYXRjaC0+bWVtW2kgKyA0XSA9IC1mZWVkYnVmZmVyW2ogKyBvdXRfdmVydGV4X3NpemUgKiAwICsgNl07CiAgICAgICAgICAgIGlmKHBhdGNoLT5tZW1baSArIDVdID09IDAuMCkKICAgICAgICAgICAgICAgIHBhdGNoLT5tZW1baSArIDVdID0gLWZlZWRidWZmZXJbaiArIG91dF92ZXJ0ZXhfc2l6ZSAqIDAgKyA3XTsKICAgICAgICAgICAgbm9ybWFsaXplX25vcm1hbChwYXRjaC0+bWVtICsgaSArIDMpOwogICAgICAgICAgICBpICs9IGQzZF9vdXRfdmVydGV4X3NpemU7CiAgICAgICAgfQogICAgfQoKICAgIGdsRGlzYWJsZShHTF9NQVAyX1ZFUlRFWF8zKTsKICAgIGdsRGlzYWJsZShHTF9BVVRPX05PUk1BTCk7CiAgICBnbERpc2FibGUoR0xfTUFQMl9OT1JNQUwpOwogICAgZ2xEaXNhYmxlKEdMX01BUDJfVEVYVFVSRV9DT09SRF80KTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgdmVydGV4IGF0dHJpYiBnZW5lcmF0aW9uIik7CiAgICBMRUFWRV9HTCgpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGZlZWRidWZmZXIpOwoKICAgIHZ0eFN0cmlkZSA9IDMgKiBzaXplb2YoZmxvYXQpOwogICAgaWYocGF0Y2gtPmhhc19ub3JtYWxzKSB7CiAgICAgICAgdnR4U3RyaWRlICs9IDMgKiBzaXplb2YoZmxvYXQpOwogICAgfQogICAgaWYocGF0Y2gtPmhhc190ZXhjb29yZHMpIHsKICAgICAgICB2dHhTdHJpZGUgKz0gNCAqIHNpemVvZihmbG9hdCk7CiAgICB9CiAgICBtZW1zZXQoJnBhdGNoLT5zdHJpZGVkLCAwLCBzaXplb2YoJnBhdGNoLT5zdHJpZGVkKSk7CiAgICBwYXRjaC0+c3RyaWRlZC51LnMucG9zaXRpb24ubHBEYXRhID0gKEJZVEUgKikgcGF0Y2gtPm1lbTsKICAgIHBhdGNoLT5zdHJpZGVkLnUucy5wb3NpdGlvbi5kd1N0cmlkZSA9IHZ0eFN0cmlkZTsKICAgIHBhdGNoLT5zdHJpZGVkLnUucy5wb3NpdGlvbi5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgcGF0Y2gtPnN0cmlkZWQudS5zLnBvc2l0aW9uLnN0cmVhbU5vID0gMjU1OwoKICAgIGlmKHBhdGNoLT5oYXNfbm9ybWFscykgewogICAgICAgIHBhdGNoLT5zdHJpZGVkLnUucy5ub3JtYWwubHBEYXRhID0gKEJZVEUgKikgcGF0Y2gtPm1lbSArIDMgKiBzaXplb2YoZmxvYXQpIC8qIHBvcyAqLzsKICAgICAgICBwYXRjaC0+c3RyaWRlZC51LnMubm9ybWFsLmR3U3RyaWRlID0gdnR4U3RyaWRlOwogICAgICAgIHBhdGNoLT5zdHJpZGVkLnUucy5ub3JtYWwuZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMzsKICAgICAgICBwYXRjaC0+c3RyaWRlZC51LnMubm9ybWFsLnN0cmVhbU5vID0gMjU1OwogICAgfQogICAgaWYocGF0Y2gtPmhhc190ZXhjb29yZHMpIHsKICAgICAgICBwYXRjaC0+c3RyaWRlZC51LnMudGV4Q29vcmRzWzBdLmxwRGF0YSA9IChCWVRFICopIHBhdGNoLT5tZW0gKyAzICogc2l6ZW9mKGZsb2F0KSAvKiBwb3MgKi87CiAgICAgICAgaWYocGF0Y2gtPmhhc19ub3JtYWxzKSB7CiAgICAgICAgICAgIHBhdGNoLT5zdHJpZGVkLnUucy50ZXhDb29yZHNbMF0ubHBEYXRhICs9IDMgKiBzaXplb2YoZmxvYXQpOwogICAgICAgIH0KICAgICAgICBwYXRjaC0+c3RyaWRlZC51LnMudGV4Q29vcmRzWzBdLmR3U3RyaWRlID0gdnR4U3RyaWRlOwogICAgICAgIHBhdGNoLT5zdHJpZGVkLnUucy50ZXhDb29yZHNbMF0uZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUNDsKICAgICAgICAvKiBNQVhfU1RSRUFNUyBpbmRleCBwb2ludHMgdG8gYW4gdW51c2VkIGVsZW1lbnQgaW4gc3RhdGVibG9jay0+c3RyZWFtT2Zmc2V0cyB3aGljaAogICAgICAgICAqIGFsd2F5cyByZW1haW5zIHNldCB0byAwLiBXaW5kb3dzIHVzZXMgc3RyZWFtIDI1NSBoZXJlLCBidXQgdGhpcyBpcyBub3QgdmlzaWJsZSB0byB0aGUKICAgICAgICAgKiBhcHBsaWNhdGlvbi4KICAgICAgICAgKi8KICAgICAgICBwYXRjaC0+c3RyaWRlZC51LnMudGV4Q29vcmRzWzBdLnN0cmVhbU5vID0gTUFYX1NUUkVBTVM7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0K