LyoKICogQ29weXJpZ2h0IDIwMDItMjAwMyBNaWNoYWVsIEf8bm5ld2lnCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCi8qIFRPRE86CiAqICAgLSBzb21lIGltcHJvdmVtZW50cyBwb3NzaWJsZQogKiAgIC0gaW1wbGVtZW50IERlY29tcHJlc3NTZXRQYWxldHRlPyAtLSBkbyB3ZSBuZWVkIGl0IGZvciBhbnl0aGluZz8KICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAibXNybGVfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2ludXNlci5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1zcmxlMzIpOwoKc3RhdGljIEhJTlNUQU5DRSBNU1JMRTMyX2hNb2R1bGUgPSAwOwoKI2RlZmluZSBBQlMoYSkgICAgICAgICAgICAgICAgKChhKSA8IDAgPyAtKGEpIDogKGEpKQojZGVmaW5lIFNRUihhKSAgICAgICAgICAgICAgICAoKGEpICogKGEpKQoKI2RlZmluZSBRVUFMSVRZX3RvX0RJU1QocSkgICAgKElDUVVBTElUWV9ISUdIIC0gcSkKc3RhdGljIGlubGluZSBXT1JEIENvbG9yQ21wKFdPUkQgY2xyMSwgV09SRCBjbHIyKQp7CiAgcmVnaXN0ZXIgVUlOVCBhID0gKGNscjEtY2xyMik7CiAgcmV0dXJuIFNRUihhKTsKfQpzdGF0aWMgaW5saW5lIFdPUkQgSW50ZW5zaXR5KFJHQlFVQUQgY2xyKQp7CiAgcmV0dXJuICgzMCAqIGNsci5yZ2JSZWQgKyA1OSAqIGNsci5yZ2JHcmVlbiArIDExICogY2xyLnJnYkJsdWUpLzQ7Cn0KCiNkZWZpbmUgR2V0UmF3UGl4ZWwobHBiaSxscCx4KSBcCiAgKChscGJpKS0+YmlCaXRDb3VudCA9PSAxID8gKChscClbKHgpLzhdID4+ICg4IC0gKHgpJTgpKSAmIDEgOiBcCiAgICgobHBiaSktPmJpQml0Q291bnQgPT0gNCA/ICgobHApWyh4KS8yXSA+PiAoNCAqICgxIC0gKHgpJTIpKSkgJiAxNSA6IGxwW3hdKSkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIHV0aWxpdHkgZnVuY3Rpb25zICovCnN0YXRpYyBCT09MICAgIGlzU3VwcG9ydGVkRElCKExQQ0JJVE1BUElORk9IRUFERVIgbHBiaSk7CnN0YXRpYyBCT09MICAgIGlzU3VwcG9ydGVkTVJMRShMUENCSVRNQVBJTkZPSEVBREVSIGxwYmkpOwpzdGF0aWMgQllURSAgICBNU1JMRTMyX0dldE5lYXJlc3RQYWxldHRlSW5kZXgoVUlOVCBjb3VudCwgY29uc3QgUkdCUVVBRCAqY2xycywgUkdCUVVBRCBjbHIpOwoKLyogY29tcHJlc3Npb24gZnVuY3Rpb25zICovCnN0YXRpYyB2b2lkICAgIGNvbXB1dGVJbnRlcm5hbEZyYW1lKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLCBjb25zdCBCWVRFICpscEluKTsKc3RhdGljIExPTkcgICAgTVNSTEUzMl9HZXRNYXhDb21wcmVzc2VkU2l6ZShMUENCSVRNQVBJTkZPSEVBREVSIGxwYmkpOwpzdGF0aWMgTFJFU1VMVCBNU1JMRTMyX0NvbXByZXNzUkxFNChjb25zdCBDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQllURSAqbHBJbiwgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscE91dCwgQk9PTCBpc0tleSk7CnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfQ29tcHJlc3NSTEU4KGNvbnN0IENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBCWVRFICpscEluLCBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwT3V0LCBCT09MIGlzS2V5KTsKCi8qIGRlY29tcHJlc3Npb24gZnVuY3Rpb25zICovCnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfRGVjb21wcmVzc1JMRTQoY29uc3QgQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpLAoJCQkJICAgICAgY29uc3QgQllURSAqbHBJbiwgTFBCWVRFIGxwT3V0KTsKc3RhdGljIExSRVNVTFQgTVNSTEUzMl9EZWNvbXByZXNzUkxFOChjb25zdCBDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmksCgkJCQkgICAgICBjb25zdCBCWVRFICpscEluLCBMUEJZVEUgbHBPdXQpOwoKLyogQVBJIGZ1bmN0aW9ucyAqLwpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0dldEZvcm1hdChDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJCSBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCk7CnN0YXRpYyBMUkVTVUxUIENvbXByZXNzR2V0U2l6ZShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJICAgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCk7CnN0YXRpYyBMUkVTVUxUIENvbXByZXNzUXVlcnkoY29uc3QgQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCSAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KTsKc3RhdGljIExSRVNVTFQgQ29tcHJlc3NCZWdpbihDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJICAgICBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpOwpzdGF0aWMgTFJFU1VMVCBDb21wcmVzcyhDb2RlY0luZm8gKnBpLCBJQ0NPTVBSRVNTKiBscGljLCBEV09SRCBkd1NpemUpOwpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0VuZChDb2RlY0luZm8gKnBpKTsKCnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NHZXRGb3JtYXQoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCQkgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCk7CnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NRdWVyeShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJICAgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCk7CnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NCZWdpbihDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJICAgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCk7CnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3MoQ29kZWNJbmZvICpwaSwgSUNERUNPTVBSRVNTICpwaWMsIERXT1JEIGR3U2l6ZSk7CnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NFbmQoQ29kZWNJbmZvICpwaSk7CnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NHZXRQYWxldHRlKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkJICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBCT09MIGlzU3VwcG9ydGVkTVJMRShMUENCSVRNQVBJTkZPSEVBREVSIGxwYmkpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChscGJpICE9IE5VTEwpOwoKICBpZiAobHBiaS0+YmlTaXplIDwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpIHx8CiAgICAgIGxwYmktPmJpUGxhbmVzICE9IDEpCiAgICByZXR1cm4gRkFMU0U7CgogIGlmIChscGJpLT5iaUNvbXByZXNzaW9uID09IEJJX1JMRTQpIHsKICAgIGlmIChscGJpLT5iaUJpdENvdW50ICE9IDQgfHwKCShscGJpLT5iaVdpZHRoICUgMikgIT0gMCkKICAgICAgcmV0dXJuIEZBTFNFOwogIH0gZWxzZSBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiA9PSBCSV9STEU4KSB7CiAgICBpZiAobHBiaS0+YmlCaXRDb3VudCAhPSA4KQogICAgICByZXR1cm4gRkFMU0U7CiAgfSBlbHNlCiAgICByZXR1cm4gRkFMU0U7CgogIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCAgaXNTdXBwb3J0ZWRESUIoTFBDQklUTUFQSU5GT0hFQURFUiBscGJpKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQobHBiaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgc3RydWN0dXJlIHZlcnNpb24vcGxhbmVzL2NvbXByZXNzaW9uICovCiAgaWYgKGxwYmktPmJpU2l6ZSA8IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSB8fAogICAgICBscGJpLT5iaVBsYW5lcyAhPSAxKQogICAgcmV0dXJuIEZBTFNFOwogIGlmIChscGJpLT5iaUNvbXByZXNzaW9uICE9IEJJX1JHQiAmJgogICAgICBscGJpLT5iaUNvbXByZXNzaW9uICE9IEJJX0JJVEZJRUxEUykKICAgIHJldHVybiBGQUxTRTsKCiAgLyogY2hlY2sgYml0LWRlcHRoICovCiAgaWYgKGxwYmktPmJpQml0Q291bnQgIT0gMSAmJgogICAgICBscGJpLT5iaUJpdENvdW50ICE9IDQgJiYKICAgICAgbHBiaS0+YmlCaXRDb3VudCAhPSA4ICYmCiAgICAgIGxwYmktPmJpQml0Q291bnQgIT0gMTUgJiYKICAgICAgbHBiaS0+YmlCaXRDb3VudCAhPSAxNiAmJgogICAgICBscGJpLT5iaUJpdENvdW50ICE9IDI0ICYmCiAgICAgIGxwYmktPmJpQml0Q291bnQgIT0gMzIpCiAgICByZXR1cm4gRkFMU0U7CgogIC8qIGNoZWNrIGZvciBzaXplKHMpICovCiAgaWYgKCFscGJpLT5iaVdpZHRoIHx8ICFscGJpLT5iaUhlaWdodCkKICAgIHJldHVybiBGQUxTRTsgLyogaW1hZ2Ugd2l0aCB6ZXJvIHNpemUsIG1ha2VzIG5vIHNlbnNlIHNvIGVycm9yICEgKi8KICBpZiAoRElCV0lEVEhCWVRFUygqbHBiaSkgKiAoRFdPUkQpbHBiaS0+YmlIZWlnaHQgPj0gKDFVTCA8PCAzMSkgLSAxKQogICAgcmV0dXJuIEZBTFNFOyAvKiBpbWFnZSB0b28gYmlnICEgKi8KCiAgLyogY2hlY2sgZm9yIG5vbmV4aXN0ZW50IGNvbG9ydGFibGUgZm9yIGhpLSBhbmQgdHJ1ZS1jb2xvciBESUIncyAqLwogIGlmIChscGJpLT5iaUJpdENvdW50ID49IDE1ICYmIGxwYmktPmJpQ2xyVXNlZCA+IDApCiAgICByZXR1cm4gRkFMU0U7CgogIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQllURSBNU1JMRTMyX0dldE5lYXJlc3RQYWxldHRlSW5kZXgoVUlOVCBjb3VudCwgY29uc3QgUkdCUVVBRCAqY2xycywgUkdCUVVBRCBjbHIpCnsKICBJTlQgIGRpZmYgPSAweDAwRkZGRkZGOwogIFVJTlQgaTsKICBVSU5UIGlkeCA9IDA7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KGNscnMgIT0gTlVMTCk7CgogIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CiAgICBpbnQgciA9ICgoaW50KWNscnNbaV0ucmdiUmVkICAgLSAoaW50KWNsci5yZ2JSZWQpOwogICAgaW50IGcgPSAoKGludCljbHJzW2ldLnJnYkdyZWVuIC0gKGludCljbHIucmdiR3JlZW4pOwogICAgaW50IGIgPSAoKGludCljbHJzW2ldLnJnYkJsdWUgIC0gKGludCljbHIucmdiQmx1ZSk7CgogICAgciA9IHIqciArIGcqZyArIGIqYjsKCiAgICBpZiAociA8IGRpZmYpIHsKICAgICAgaWR4ICA9IGk7CiAgICAgIGRpZmYgPSByOwogICAgICBpZiAoZGlmZiA9PSAwKQoJYnJlYWs7CiAgICB9CiAgfQoKICByZXR1cm4gaWR4Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp2b2lkIGNvbXB1dGVJbnRlcm5hbEZyYW1lKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLCBjb25zdCBCWVRFICpscEluKQp7CiAgV09SRCAgIHdJbnRlbnNpdHlUYmxbMjU2XTsKICBEV09SRCAgbEluTGluZSwgbE91dExpbmU7CiAgTFBXT1JEIGxwT3V0OwogIFVJTlQgICBpOwogIExPTkcgICB5OwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChwaSAhPSBOVUxMICYmIGxwYmlJbiAhPSBOVUxMICYmIGxwSW4gIT0gTlVMTCk7CiAgYXNzZXJ0KHBpLT5wQ3VyRnJhbWUgIT0gTlVMTCk7CgogIGxJbkxpbmUgID0gRElCV0lEVEhCWVRFUygqbHBiaUluKTsKICBsT3V0TGluZSA9IFdJRFRIQllURVMoKFdPUkQpbHBiaUluLT5iaVdpZHRoICogOHUgKiBzaXplb2YoV09SRCkpIC8gMnU7CiAgbHBPdXQgICAgPSBwaS0+cEN1ckZyYW1lOwoKICBhc3NlcnQobHBiaUluLT5iaUNsclVzZWQgIT0gMCk7CgogIHsKICAgIGNvbnN0IFJHQlFVQUQgKmxwID0KICAgICAgKGNvbnN0IFJHQlFVQUQgKikoKGNvbnN0IEJZVEUqKWxwYmlJbiArIGxwYmlJbi0+YmlTaXplKTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbHBiaUluLT5iaUNsclVzZWQ7IGkrKykKICAgICAgd0ludGVuc2l0eVRibFtpXSA9IEludGVuc2l0eShscFtpXSk7CiAgfQoKICBmb3IgKHkgPSAwOyB5IDwgbHBiaUluLT5iaUhlaWdodDsgeSsrKSB7CiAgICBMT05HIHg7CgogICAgc3dpdGNoIChscGJpSW4tPmJpQml0Q291bnQpIHsKICAgIGNhc2UgMToKICAgICAgZm9yICh4ID0gMDsgeCA8IGxwYmlJbi0+YmlXaWR0aCAvIDg7IHgrKykgewoJZm9yIChpID0gMDsgaSA8IDc7IGkrKykKCSAgbHBPdXRbOCAqIHggKyBpXSA9IHdJbnRlbnNpdHlUYmxbKGxwSW5beF0gPj4gKDcgLSBpKSkgJiAxXTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgNDoKICAgICAgZm9yICh4ID0gMDsgeCA8IGxwYmlJbi0+YmlXaWR0aCAvIDI7IHgrKykgewoJbHBPdXRbMiAqIHggKyAwXSA9IHdJbnRlbnNpdHlUYmxbKGxwSW5beF0gPj4gNCldOwoJbHBPdXRbMiAqIHggKyAxXSA9IHdJbnRlbnNpdHlUYmxbKGxwSW5beF0gJiAweDBGKV07CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIDg6CiAgICAgIGZvciAoeCA9IDA7IHggPCBscGJpSW4tPmJpV2lkdGg7IHgrKykKCWxwT3V0W3hdID0gd0ludGVuc2l0eVRibFtscEluW3hdXTsKICAgICAgYnJlYWs7CiAgICB9CgogICAgbHBJbiAgKz0gbEluTGluZTsKICAgIGxwT3V0ICs9IGxPdXRMaW5lOwogIH0KfQoKc3RhdGljIExPTkcgTVNSTEUzMl9HZXRNYXhDb21wcmVzc2VkU2l6ZShMUENCSVRNQVBJTkZPSEVBREVSIGxwYmkpCnsKICBMT05HIGEsIGIsIHNpemU7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQobHBiaSAhPSBOVUxMKTsKCiAgYSA9IGxwYmktPmJpV2lkdGggLyAyNTU7CiAgYiA9IGxwYmktPmJpV2lkdGggJSAyNTU7CiAgaWYgKGxwYmktPmJpQml0Q291bnQgPD0gNCkgewogICAgYSAvPSAyOwogICAgYiAvPSAyOwogIH0KCiAgc2l6ZSA9ICgyICsgYSAqICgyICsgKChhICsgMikgJiB+MikpICsgYiAqICgyICsgKChiICsgMikgJiB+MikpKTsKICByZXR1cm4gc2l6ZSAqIGxwYmktPmJpSGVpZ2h0Owp9CgovKiBscFAgPT4gY3VycmVudCAgcG9zIGluIHByZXZpb3VzIGZyYW1lCiAqIGxwQSA9PiBwcmV2aW91cyBwb3MgaW4gY3VycmVudCAgZnJhbWUKICogbHBCID0+IGN1cnJlbnQgIHBvcyBpbiBjdXJyZW50ICBmcmFtZQogKi8Kc3RhdGljIElOVCBjb3VudERpZmZSTEU0KGNvbnN0IFdPUkQgKmxwUCwgY29uc3QgV09SRCAqbHBBLCBjb25zdCBXT1JEICpscEIsIElOVCBwb3MsIExPTkcgbERpc3QsIExPTkcgd2lkdGgpCnsKICBJTlQgIGNvdW50OwogIFdPUkQgY2xyMSwgY2xyMjsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQobHBBICYmIGxwQiAmJiBsRGlzdCA+PSAwICYmIHdpZHRoID4gMCk7CgogIGlmIChwb3MgPj0gd2lkdGgpCiAgICByZXR1cm4gMDsKICBpZiAocG9zKzEgPT0gd2lkdGgpCiAgICByZXR1cm4gMTsKCiAgY2xyMSA9IGxwQltwb3MrK107CiAgY2xyMiA9IGxwQltwb3NdOwoKICBjb3VudCA9IDI7CiAgd2hpbGUgKHBvcyArIDEgPCB3aWR0aCkgewogICAgV09SRCBjbHIzLCBjbHI0OwoKICAgIGNscjMgPSBscEJbKytwb3NdOwogICAgaWYgKHBvcyArIDEgPj0gd2lkdGgpCiAgICAgIHJldHVybiBjb3VudCArIDE7CgogICAgY2xyNCA9IGxwQlsrK3Bvc107CiAgICBpZiAoQ29sb3JDbXAoY2xyMSwgY2xyMykgPD0gbERpc3QgJiYKCUNvbG9yQ21wKGNscjIsIGNscjQpIDw9IGxEaXN0KSB7CiAgICAgIC8qIGRpZmYgYXQgZW5kPyAtLSBsb29rLWFoZWFkIGZvciBhdCBsZWFzdCA/PyBtb3JlIGVuY29kYWJsZSBwaXhlbHMgKi8KICAgICAgaWYgKHBvcyArIDIgPCB3aWR0aCAmJiBDb2xvckNtcChjbHIxLGxwQltwb3MrMV0pIDw9IGxEaXN0ICYmCgkgIENvbG9yQ21wKGNscjIsbHBCW3BvcysyXSkgPD0gbERpc3QpIHsKCWlmIChwb3MgKyA0IDwgd2lkdGggJiYgQ29sb3JDbXAobHBCW3BvcysxXSxscEJbcG9zKzNdKSA8PSBsRGlzdCAmJgoJICAgIENvbG9yQ21wKGxwQltwb3MrMl0sbHBCW3Bvcys0XSkgPD0gbERpc3QpCgkgIHJldHVybiBjb3VudCAtIDM7IC8qIGZvbGxvd2VkIGJ5IGF0IGxlYXN0IDQgZW5jb2RhYmxlIHBpeGVscyAqLwoJcmV0dXJuIGNvdW50IC0gMjsKICAgICAgfQogICAgfSBlbHNlIGlmIChscFAgIT0gTlVMTCAmJiBDb2xvckNtcChscFBbcG9zXSwgbHBCW3Bvc10pIDw9IGxEaXN0KSB7CiAgICAgIC8qICdjb21wYXJlJyB3aXRoIHByZXZpb3VzIGZyYW1lIGZvciBlbmQgb2YgZGlmZiAqLwogICAgICBJTlQgY291bnQyID0gMDsKCiAgICAgIC8qIEZJWE1FICovCgogICAgICBpZiAoY291bnQyID49IDgpCglyZXR1cm4gY291bnQ7CgogICAgICBwb3MgLT0gY291bnQyOwogICAgfQoKICAgIGNvdW50ICs9IDI7CiAgICBjbHIxID0gY2xyMzsKICAgIGNscjIgPSBjbHI0OwogIH0KCiAgcmV0dXJuIGNvdW50Owp9CgovKiBscFAgPT4gY3VycmVudCAgcG9zIGluIHByZXZpb3VzIGZyYW1lCiAqIGxwQSA9PiBwcmV2aW91cyBwb3MgaW4gY3VycmVudCAgZnJhbWUKICogbHBCID0+IGN1cnJlbnQgIHBvcyBpbiBjdXJyZW50ICBmcmFtZQogKi8Kc3RhdGljIElOVCBjb3VudERpZmZSTEU4KGNvbnN0IFdPUkQgKmxwUCwgY29uc3QgV09SRCAqbHBBLCBjb25zdCBXT1JEICpscEIsIElOVCBwb3MsIExPTkcgbERpc3QsIExPTkcgd2lkdGgpCnsKICBJTlQgY291bnQ7CgogIGZvciAoY291bnQgPSAwOyBwb3MgPCB3aWR0aDsgcG9zKyssIGNvdW50KyspIHsKICAgIGlmIChDb2xvckNtcChscEFbcG9zXSwgbHBCW3Bvc10pIDw9IGxEaXN0KSB7CiAgICAgIC8qIGRpZmYgYXQgZW5kPyAtLSBsb29rLWFoZWFkIGZvciBzb21lIG1vcmUgZW5jb2RhYmxlIHBpeGVsICovCiAgICAgIGlmIChwb3MgKyAxIDwgd2lkdGggJiYgQ29sb3JDbXAobHBCW3Bvc10sIGxwQltwb3MrMV0pIDw9IGxEaXN0KQoJcmV0dXJuIGNvdW50IC0gMTsKICAgICAgaWYgKHBvcyArIDIgPCB3aWR0aCAmJiBDb2xvckNtcChscEJbcG9zKzFdLCBscEJbcG9zKzJdKSA8PSBsRGlzdCkKCXJldHVybiBjb3VudCAtIDE7CiAgICB9IGVsc2UgaWYgKGxwUCAhPSBOVUxMICYmIENvbG9yQ21wKGxwUFtwb3NdLCBscEJbcG9zXSkgPD0gbERpc3QpIHsKICAgICAgLyogJ2NvbXBhcmUnIHdpdGggcHJldmlvdXMgZnJhbWUgZm9yIGVuZCBvZiBkaWZmICovCiAgICAgIElOVCBjb3VudDIgPSAwOwoKICAgICAgZm9yIChjb3VudDIgPSAwLCBwb3MrKzsgcG9zIDwgd2lkdGggJiYgY291bnQyIDw9IDU7IHBvcysrLCBjb3VudDIrKykgewoJaWYgKENvbG9yQ21wKGxwUFtwb3NdLCBscEJbcG9zXSkgPiBsRGlzdCkKCSAgYnJlYWs7CiAgICAgIH0KICAgICAgaWYgKGNvdW50MiA+IDQpCglyZXR1cm4gY291bnQ7CgogICAgICBwb3MgLT0gY291bnQyOwogICAgfQogIH0KCiAgcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgSU5UIE1TUkxFMzJfQ29tcHJlc3NSTEU0TGluZShjb25zdCBDb2RlY0luZm8gKnBpLCBjb25zdCBXT1JEICpscFAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFdPUkQgKmxwQywgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBCWVRFICpscEluLCBMT05HIGxEaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgeCwgTFBCWVRFICpwcE91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKmxwU2l6ZUltYWdlKQp7CiAgTFBCWVRFIGxwT3V0ID0gKnBwT3V0OwogIElOVCAgICBjb3VudCwgcG9zOwogIFdPUkQgICBjbHIxLCBjbHIyOwoKICAvKiB0cnkgdG8gZW5jb2RlIGFzIG1hbnkgcGl4ZWwgYXMgcG9zc2libGUgKi8KICBjb3VudCA9IDE7CiAgcG9zICAgPSB4OwogIGNscjEgID0gbHBDW3BvcysrXTsKICBpZiAocG9zIDwgbHBiaS0+YmlXaWR0aCkgewogICAgY2xyMiA9IGxwQ1twb3NdOwogICAgZm9yICgrK2NvdW50OyBwb3MgKyAxIDwgbHBiaS0+YmlXaWR0aDsgKSB7CiAgICAgICsrcG9zOwogICAgICBpZiAoQ29sb3JDbXAoY2xyMSwgbHBDW3Bvc10pID4gbERpc3QpCglicmVhazsKICAgICAgY291bnQrKzsKICAgICAgaWYgKHBvcyArIDEgPj0gbHBiaS0+YmlXaWR0aCkKCWJyZWFrOwogICAgICArK3BvczsKICAgICAgaWYgKENvbG9yQ21wKGNscjIsIGxwQ1twb3NdKSA+IGxEaXN0KQoJYnJlYWs7CiAgICAgIGNvdW50Kys7CiAgICB9CiAgfQoKICBpZiAoY291bnQgPCA0KSB7CiAgICAvKiBhZGQgc29tZSBwaXhlbCBmb3IgYWJzb2x1dGluZyBpZiBwb3NzaWJsZSAqLwogICAgY291bnQgKz0gY291bnREaWZmUkxFNChscFAsIGxwQyAtIDEsIGxwQywgcG9zLTEsIGxEaXN0LCBscGJpLT5iaVdpZHRoKTsKCiAgICBhc3NlcnQoY291bnQgPiAwKTsKCiAgICAvKiBjaGVjayBmb3IgbmVhciBlbmQgb2YgbGluZSAqLwogICAgaWYgKHggKyBjb3VudCA+IGxwYmktPmJpV2lkdGgpCiAgICAgIGNvdW50ID0gbHBiaS0+YmlXaWR0aCAtIHg7CgogICAgLyogYWJzb2x1dGUgcGl4ZWwocykgaW4gZ3JvdXBzIG9mIGF0IGxlYXN0IDMgYW5kIGF0IG1vc3QgMjU0IHBpeGVscyAqLwogICAgd2hpbGUgKGNvdW50ID4gMikgewogICAgICBJTlQgIGk7CiAgICAgIElOVCAgc2l6ZSAgICAgICA9IG1pbihjb3VudCwgMjU0KTsKICAgICAgaW50ICBieXRlcyAgICAgID0gKChzaXplICsgMSkgJiAofjEpKSAvIDI7CiAgICAgIEJPT0wgZXh0cmFfYnl0ZSA9IGJ5dGVzICYgMHgwMTsKCiAgICAgICpscFNpemVJbWFnZSArPSAyICsgYnl0ZXMgKyBleHRyYV9ieXRlOwogICAgICBhc3NlcnQoKCgqbHBTaXplSW1hZ2UpICUgMikgPT0gMCk7CiAgICAgIGNvdW50IC09IHNpemU7CiAgICAgICpscE91dCsrID0gMDsKICAgICAgKmxwT3V0KysgPSBzaXplOwogICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSArPSAyKSB7CgljbHIxID0gcGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4KV07Cgl4Kys7CglpZiAoaSArIDEgPCBzaXplKSB7CgkgIGNscjIgPSBwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXTsKCSAgeCsrOwoJfSBlbHNlCgkgIGNscjIgPSAwOwoKCSpscE91dCsrID0gKGNscjEgPDwgNCkgfCBjbHIyOwogICAgICB9CiAgICAgIGlmIChleHRyYV9ieXRlKQoJKmxwT3V0KysgPSAwOwogICAgfQoKICAgIGlmIChjb3VudCA+IDApIHsKICAgICAgLyogdG9vIGxpdHRsZSBmb3IgYWJzb2x1dGluZyBzbyB3ZSBtdXN0IGVuY29kZSB0aGVtICovCiAgICAgIGFzc2VydChjb3VudCA8PSAyKTsKCiAgICAgICpscFNpemVJbWFnZSArPSAyOwogICAgICBjbHIxID0gcGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4KV07CiAgICAgIHgrKzsKICAgICAgaWYgKGNvdW50ID09IDIpIHsKCWNscjIgPSBwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXTsKCXgrKzsKICAgICAgfSBlbHNlCgljbHIyID0gMDsKICAgICAgKmxwT3V0KysgPSBjb3VudDsKICAgICAgKmxwT3V0KysgPSAoY2xyMSA8PCA0KSB8IGNscjI7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIGVuY29kZSBjb3VudCBwaXhlbChzKSAqLwogICAgY2xyMSA9ICgocGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4KV0gPDwgNCkgfAoJICAgIHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCArIDEpXSk7CgogICAgeCArPSBjb3VudDsKICAgIHdoaWxlIChjb3VudCA+IDApIHsKICAgICAgSU5UIHNpemUgPSBtaW4oY291bnQsIDI1NCk7CgogICAgICAqbHBTaXplSW1hZ2UgKz0gMjsKICAgICAgY291bnQgICAgLT0gc2l6ZTsKICAgICAgKmxwT3V0KysgID0gc2l6ZTsKICAgICAgKmxwT3V0KysgID0gY2xyMTsKICAgIH0KICB9CgogICpwcE91dCA9IGxwT3V0OwoKICByZXR1cm4geDsKfQoKc3RhdGljIElOVCBNU1JMRTMyX0NvbXByZXNzUkxFOExpbmUoY29uc3QgQ29kZWNJbmZvICpwaSwgY29uc3QgV09SRCAqbHBQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBXT1JEICpscEMsIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQllURSAqbHBJbiwgTE9ORyBsRGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHgsIExQQllURSAqcHBPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpscFNpemVJbWFnZSkKewogIExQQllURSBscE91dCA9ICpwcE91dDsKICBJTlQgICAgY291bnQsIHBvczsKICBXT1JEICAgY2xyOwoKICBhc3NlcnQobHBiaS0+YmlCaXRDb3VudCA8PSA4KTsKICBhc3NlcnQobHBiaS0+YmlDb21wcmVzc2lvbiA9PSBCSV9SR0IpOwoKICAvKiB0cnkgdG8gZW5jb2RlIGFzIG11Y2ggYXMgcG9zc2libGUgKi8KICBwb3MgPSB4OwogIGNsciA9IGxwQ1twb3MrK107CiAgZm9yIChjb3VudCA9IDE7IHBvcyA8IGxwYmktPmJpV2lkdGg7IGNvdW50KyspIHsKICAgIGlmIChDb2xvckNtcChjbHIsIGxwQ1twb3MrK10pID4gbERpc3QpCiAgICAgIGJyZWFrOwogIH0KCiAgaWYgKGNvdW50IDwgMikgewogICAgLyogYWRkIHNvbWUgbW9yZSBwaXhlbHMgZm9yIGFic29sdXRpbmcgaWYgcG9zc2libGUgKi8KICAgIGNvdW50ICs9IGNvdW50RGlmZlJMRTgobHBQLCBscEMgLSAxLCBscEMsIHBvcy0xLCBsRGlzdCwgbHBiaS0+YmlXaWR0aCk7CgogICAgYXNzZXJ0KGNvdW50ID4gMCk7CgogICAgLyogY2hlY2sgZm9yIG92ZXIgZW5kIG9mIGxpbmUgKi8KICAgIGlmICh4ICsgY291bnQgPiBscGJpLT5iaVdpZHRoKQogICAgICBjb3VudCA9IGxwYmktPmJpV2lkdGggLSB4OwoKICAgIC8qIGFic29sdXRlIHBpeGVsKHMpIGluIGdyb3VwcyBvZiBhdCBsZWFzdCAzIGFuZCBhdCBtb3N0IDI1NSBwaXhlbHMgKi8KICAgIHdoaWxlIChjb3VudCA+IDIpIHsKICAgICAgSU5UICBpOwogICAgICBJTlQgIHNpemUgICAgICAgPSBtaW4oY291bnQsIDI1NSk7CiAgICAgIEJPT0wgZXh0cmFfYnl0ZSA9IHNpemUgJSAyOwoKICAgICAgKmxwU2l6ZUltYWdlICs9IDIgKyBzaXplICsgZXh0cmFfYnl0ZTsKICAgICAgY291bnQgLT0gc2l6ZTsKICAgICAgKmxwT3V0KysgPSAwOwogICAgICAqbHBPdXQrKyA9IHNpemU7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCSpscE91dCsrID0gcGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4KV07Cgl4Kys7CiAgICAgIH0KICAgICAgaWYgKGV4dHJhX2J5dGUpCgkqbHBPdXQrKyA9IDA7CiAgICB9CiAgICBpZiAoY291bnQgPiAwKSB7CiAgICAgIC8qIHRvbyBsaXR0bGUgZm9yIGFic29sdXRpbmcgc28gd2UgbXVzdCBlbmNvZGUgdGhlbSBldmVuIGlmIGl0J3MgZXhwZW5zaXZlISAqLwogICAgICBhc3NlcnQoY291bnQgPD0gMik7CgogICAgICAqbHBTaXplSW1hZ2UgKz0gMiAqIGNvdW50OwogICAgICAqbHBPdXQrKyA9IDE7CiAgICAgICpscE91dCsrID0gcGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4KV07CiAgICAgIHgrKzsKCiAgICAgIGlmIChjb3VudCA9PSAyKSB7CgkqbHBPdXQrKyA9IDE7CgkqbHBPdXQrKyA9IHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCldOwoJeCsrOwogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIGVuY29kZSBjb3VudCBwaXhlbChzKSAqLwogICAgY2xyID0gcGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4KV07CgogICAgLyogb3B0aW1pemUgZW5kIG9mIGxpbmUgKi8KICAgIGlmICh4ICsgY291bnQgKyAxID09IGxwYmktPmJpV2lkdGgpCiAgICAgIGNvdW50Kys7CgogICAgeCArPSBjb3VudDsKICAgIHdoaWxlIChjb3VudCA+IDApIHsKICAgICAgSU5UIHNpemUgPSBtaW4oY291bnQsIDI1NSk7CgogICAgICAqbHBTaXplSW1hZ2UgKz0gMjsKICAgICAgY291bnQgICAgLT0gc2l6ZTsKICAgICAgKmxwT3V0KysgID0gc2l6ZTsKICAgICAgKmxwT3V0KysgID0gY2xyOwogICAgfQogIH0KCiAgKnBwT3V0ID0gbHBPdXQ7CgogIHJldHVybiB4Owp9CgpMUkVTVUxUIE1TUkxFMzJfQ29tcHJlc3NSTEU0KGNvbnN0IENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEJZVEUgKmxwSW4sIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBscE91dCwgQk9PTCBpc0tleSkKewogIExQV09SRCBscEM7CiAgTE9ORyAgIGxMaW5lLCBsSW5MaW5lLCBsRGlzdDsKICBMUEJZVEUgbHBPdXRTdGFydCA9IGxwT3V0OwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChwaSAhPSBOVUxMICYmIGxwYmlPdXQgIT0gTlVMTCk7CiAgYXNzZXJ0KGxwSW4gIT0gTlVMTCAmJiBscE91dCAhPSBOVUxMKTsKICBhc3NlcnQocGktPnBDdXJGcmFtZSAhPSBOVUxMKTsKCiAgbHBDICAgICAgPSBwaS0+cEN1ckZyYW1lOwogIGxEaXN0ICAgID0gUVVBTElUWV90b19ESVNUKHBpLT5kd1F1YWxpdHkpOwogIGxJbkxpbmUgID0gRElCV0lEVEhCWVRFUygqbHBiaUluKTsKICBsTGluZSAgICA9IFdJRFRIQllURVMobHBiaU91dC0+YmlXaWR0aCAqIDE2KSAvIDI7CgogIGxwYmlPdXQtPmJpU2l6ZUltYWdlID0gMDsKICBpZiAoaXNLZXkpIHsKICAgIC8qIGtleWZyYW1lIC0tIGNvbnZlcnQgaW50ZXJuYWwgZnJhbWUgdG8gb3V0cHV0IGZvcm1hdCAqLwogICAgSU5UIHgsIHk7CgogICAgZm9yICh5ID0gMDsgeSA8IGxwYmlPdXQtPmJpSGVpZ2h0OyB5KyspIHsKICAgICAgeCA9IDA7CgogICAgICBkbyB7Cgl4ID0gTVNSTEUzMl9Db21wcmVzc1JMRTRMaW5lKHBpLCBOVUxMLCBscEMsIGxwYmlJbiwgbHBJbiwgbERpc3QsIHgsCgkJCQkgICAgICZscE91dCwgJmxwYmlPdXQtPmJpU2l6ZUltYWdlKTsKICAgICAgfSB3aGlsZSAoeCA8IGxwYmlPdXQtPmJpV2lkdGgpOwoKICAgICAgbHBDICAgKz0gbExpbmU7CiAgICAgIGxwSW4gICs9IGxJbkxpbmU7CgogICAgICAvKiBhZGQgRU9MIC0tIGVuZCBvZiBsaW5lICovCiAgICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDI7CiAgICAgICooTFBXT1JEKWxwT3V0ID0gMDsKICAgICAgbHBPdXQgKz0gc2l6ZW9mKFdPUkQpOwogICAgICBhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiBkZWx0YS1mcmFtZSAtLSBjb21wdXRlIGRlbHRhIGJldHdlZW4gbGFzdCBhbmQgdGhpcyBpbnRlcm5hbCBmcmFtZSAqLwogICAgTFBXT1JEIGxwUDsKICAgIElOVCAgICB4LCB5OwogICAgSU5UICAgIGp1bXB4LCBqdW1weTsKCiAgICBhc3NlcnQocGktPnBQcmV2RnJhbWUgIT0gTlVMTCk7CgogICAgbHBQICAgPSBwaS0+cFByZXZGcmFtZTsKICAgIGp1bXB5ID0gMDsKICAgIGp1bXB4ID0gLTE7CgogICAgZm9yICh5ID0gMDsgeSA8IGxwYmlPdXQtPmJpSGVpZ2h0OyB5KyspIHsKICAgICAgeCA9IDA7CgogICAgICBkbyB7CglJTlQgY291bnQsIHBvczsKCglpZiAoanVtcHggPT0gLTEpCgkgIGp1bXB4ID0geDsKCWZvciAoY291bnQgPSAwLCBwb3MgPSB4OyBwb3MgPCBscGJpT3V0LT5iaVdpZHRoOyBwb3MrKywgY291bnQrKykgewoJICBpZiAoQ29sb3JDbXAobHBQW3Bvc10sIGxwQ1twb3NdKSA+IGxEaXN0KQoJICAgIGJyZWFrOwoJfQoKCWlmIChwb3MgPT0gbHBiaU91dC0+YmlXaWR0aCAmJiBjb3VudCA+IDgpIHsKCSAgLyogKGNvdW50ID4gOCkgc2VjdXJlcyB0aGF0IHdlIHdpbGwgc2F2ZSBzcGFjZSAqLwoJICBqdW1weSsrOwoJICBicmVhazsKCX0gZWxzZSBpZiAoanVtcHkgfHwganVtcHggIT0gcG9zKSB7CgkgIC8qIHRpbWUgdG8ganVtcCAqLwoJICBhc3NlcnQoanVtcHggIT0gLTEpOwoKCSAgaWYgKHBvcyA8IGp1bXB4KSB7CgkgICAgLyogY2FuIG9ubHkganVtcCBpbiBwb3NpdGl2ZSBkaXJlY3Rpb24gLS0ganVtcCB1bnRpbCBFT0wsIEVPTCAqLwoJICAgIElOVCB3ID0gbHBiaU91dC0+YmlXaWR0aCAtIGp1bXB4OwoKCSAgICBhc3NlcnQoanVtcHkgPiAwKTsKCSAgICBhc3NlcnQodyA+PSA0KTsKCgkgICAganVtcHggPSAwOwoJICAgIGp1bXB5LS07CgkgICAgLyogaWYgKHcgJSAyNTUgPT0gMikgdGhlbiBlcXVhbCBjb3N0cwoJICAgICAqIGVsc2UgaWYgKHcgJSAyNTUgPCA0ICYmIHdlIGNvdWxkIGVuY29kZSBhbGwpIHRoZW4gMiBieXRlcyB0b28gZXhwZW5zaXZlCgkgICAgICogZWxzZSBpdCB3aWxsIGJlIGNoZWFwZXIKCSAgICAgKi8KCSAgICB3aGlsZSAodyA+IDApIHsKCSAgICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDQ7CgkgICAgICAqbHBPdXQrKyA9IDA7CgkgICAgICAqbHBPdXQrKyA9IDI7CgkgICAgICAqbHBPdXQgICA9IG1pbih3LCAyNTUpOwoJICAgICAgdyAgICAgICAtPSAqbHBPdXQrKzsKCSAgICAgICpscE91dCsrID0gMDsKCSAgICB9CgkgICAgLyogYWRkIEVPTCAtLSBlbmQgb2YgbGluZSAqLwoJICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDI7CgkgICAgKigoTFBXT1JEKWxwT3V0KSA9IDA7CgkgICAgbHBPdXQgKz0gc2l6ZW9mKFdPUkQpOwoJICB9CgoJICAvKiBGSVhNRTogaWYgKGp1bXB5ID09IDAgJiYgY291bGQgZW5jb2RlIGFsbCkgdGhlbiBqdW1wIHRvbyBleHBlbnNpdmUgKi8KCgkgIC8qIHdyaXRlIG91dCByZWFsIGp1bXAocykgKi8KCSAgd2hpbGUgKGp1bXB5IHx8IHBvcyAhPSBqdW1weCkgewoJICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDQ7CgkgICAgKmxwT3V0KysgPSAwOwoJICAgICpscE91dCsrID0gMjsKCSAgICAqbHBPdXQgICA9IG1pbihwb3MgLSBqdW1weCwgMjU1KTsKCSAgICB4ICAgICAgICs9ICpscE91dDsKCSAgICBqdW1weCAgICs9ICpscE91dCsrOwoJICAgICpscE91dCAgID0gbWluKGp1bXB5LCAyNTUpOwoJICAgIGp1bXB5ICAgLT0gKmxwT3V0Kys7CgkgIH0KCgkgIGp1bXB5ID0gMDsKCX0KCglqdW1weCA9IC0xOwoKCWlmICh4IDwgbHBiaU91dC0+YmlXaWR0aCkgewoJICAvKiBza2lwcGVkIHRoZSAnc2FtZScgdGhpbmdzIGNvcnJlc3BvbmRpbmcgdG8gcHJldmlvdXMgZnJhbWUgKi8KCSAgeCA9IE1TUkxFMzJfQ29tcHJlc3NSTEU0TGluZShwaSwgbHBQLCBscEMsIGxwYmlJbiwgbHBJbiwgbERpc3QsIHgsCgkJCSAgICAgICAmbHBPdXQsICZscGJpT3V0LT5iaVNpemVJbWFnZSk7Cgl9CiAgICAgIH0gd2hpbGUgKHggPCBscGJpT3V0LT5iaVdpZHRoKTsKCiAgICAgIGxwUCAgICs9IGxMaW5lOwogICAgICBscEMgICArPSBsTGluZTsKICAgICAgbHBJbiAgKz0gbEluTGluZTsKCiAgICAgIGlmIChqdW1weSA9PSAwKSB7Cglhc3NlcnQoanVtcHggPT0gLTEpOwoKCS8qIGFkZCBFT0wgLS0gZW5kIG9mIGxpbmUgKi8KCWxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDI7CgkqKChMUFdPUkQpbHBPdXQpID0gMDsKICAgICAgICBscE91dCArPSBzaXplb2YoV09SRCk7Cglhc3NlcnQobHBPdXQgPT0gbHBPdXRTdGFydCArIGxwYmlPdXQtPmJpU2l6ZUltYWdlKTsKICAgICAgfQogICAgfQoKICAgIC8qIGFkZCBFT0wgLS0gd2lsbCBiZSBjaGFuZ2VkIHRvIEVPSSAqLwogICAgbHBiaU91dC0+YmlTaXplSW1hZ2UgKz0gMjsKICAgICooKExQV09SRClscE91dCkgPSAwOwogICAgbHBPdXQgKz0gc2l6ZW9mKFdPUkQpOwogIH0KCiAgLyogY2hhbmdlIEVPTCB0byBFT0kgLS0gZW5kIG9mIGltYWdlICovCiAgbHBPdXRbLTFdID0gMTsKICBhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCkxSRVNVTFQgTVNSTEUzMl9Db21wcmVzc1JMRTgoY29uc3QgQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQllURSAqbHBJbiwgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIGxwT3V0LCBCT09MIGlzS2V5KQp7CiAgTFBXT1JEIGxwQzsKICBMT05HICAgbERpc3QsIGxJbkxpbmUsIGxMaW5lOwogIExQQllURSBscE91dFN0YXJ0ID0gbHBPdXQ7CgogIGFzc2VydChwaSAhPSBOVUxMICYmIGxwYmlPdXQgIT0gTlVMTCk7CiAgYXNzZXJ0KGxwSW4gIT0gTlVMTCAmJiBscE91dCAhPSBOVUxMKTsKICBhc3NlcnQocGktPnBDdXJGcmFtZSAhPSBOVUxMKTsKCiAgbHBDICAgICA9IHBpLT5wQ3VyRnJhbWU7CiAgbERpc3QgICA9IFFVQUxJVFlfdG9fRElTVChwaS0+ZHdRdWFsaXR5KTsKICBsSW5MaW5lID0gRElCV0lEVEhCWVRFUygqbHBiaUluKTsKICBsTGluZSAgID0gV0lEVEhCWVRFUyhscGJpT3V0LT5iaVdpZHRoICogMTYpIC8gMjsKCiAgbHBiaU91dC0+YmlTaXplSW1hZ2UgPSAwOwogIGlmIChpc0tleSkgewogICAgLyoga2V5ZnJhbWUgLS0gY29udmVydCBpbnRlcm5hbCBmcmFtZSB0byBvdXRwdXQgZm9ybWF0ICovCiAgICBJTlQgeCwgeTsKCiAgICBmb3IgKHkgPSAwOyB5IDwgbHBiaU91dC0+YmlIZWlnaHQ7IHkrKykgewogICAgICB4ID0gMDsKCiAgICAgIGRvIHsKCXggPSBNU1JMRTMyX0NvbXByZXNzUkxFOExpbmUocGksIE5VTEwsIGxwQywgbHBiaUluLCBscEluLCBsRGlzdCwgeCwKCQkJICAgICAmbHBPdXQsICZscGJpT3V0LT5iaVNpemVJbWFnZSk7Cglhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwogICAgICB9IHdoaWxlICh4IDwgbHBiaU91dC0+YmlXaWR0aCk7CgogICAgICBscEMgICs9IGxMaW5lOwogICAgICBscEluICs9IGxJbkxpbmU7CgogICAgICAvKiBhZGQgRU9MIC0tIGVuZCBvZiBsaW5lICovCiAgICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDI7CiAgICAgICooKExQV09SRClscE91dCkgPSAwOwogICAgICBscE91dCArPSBzaXplb2YoV09SRCk7CiAgICAgIGFzc2VydChscE91dCA9PSAobHBPdXRTdGFydCArIGxwYmlPdXQtPmJpU2l6ZUltYWdlKSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIGRlbHRhLWZyYW1lIC0tIGNvbXB1dGUgZGVsdGEgYmV0d2VlbiBsYXN0IGFuZCB0aGlzIGludGVybmFsIGZyYW1lICovCiAgICBMUFdPUkQgbHBQOwogICAgSU5UICAgIHgsIHk7CiAgICBJTlQgICAganVtcHgsIGp1bXB5OwoKICAgIGFzc2VydChwaS0+cFByZXZGcmFtZSAhPSBOVUxMKTsKCiAgICBscFAgICA9IHBpLT5wUHJldkZyYW1lOwogICAganVtcHggPSAtMTsKICAgIGp1bXB5ID0gMDsKCiAgICBmb3IgKHkgPSAwOyB5IDwgbHBiaU91dC0+YmlIZWlnaHQ7IHkrKykgewogICAgICB4ID0gMDsKCiAgICAgIGRvIHsKCUlOVCBjb3VudCwgcG9zOwoKCWlmIChqdW1weCA9PSAtMSkKCSAganVtcHggPSB4OwoJZm9yIChjb3VudCA9IDAsIHBvcyA9IHg7IHBvcyA8IGxwYmlPdXQtPmJpV2lkdGg7IHBvcysrLCBjb3VudCsrKSB7CgkgIGlmIChDb2xvckNtcChscFBbcG9zXSwgbHBDW3Bvc10pID4gbERpc3QpCgkgICAgYnJlYWs7Cgl9CgoJaWYgKHBvcyA9PSBscGJpT3V0LT5iaVdpZHRoICYmIGNvdW50ID4gNCkgewoJICAvKiAoY291bnQgPiA0KSBzZWN1cmVzIHRoYXQgd2Ugd2lsbCBzYXZlIHNwYWNlICovCgkgIGp1bXB5Kys7CgkgIGJyZWFrOwoJfSBlbHNlIGlmIChqdW1weSB8fCBqdW1weCAhPSBwb3MpIHsKCSAgLyogdGltZSB0byBqdW1wICovCgkgIGFzc2VydChqdW1weCAhPSAtMSk7CgoJICBpZiAocG9zIDwganVtcHgpIHsKCSAgICAvKiBjYW4gb25seSBqdW1wIGluIHBvc2l0aXZlIGRpcmVjdGlvbiAtLSBkbyBhbiBFT0wgdGhlbiBqdW1wICovCgkgICAgYXNzZXJ0KGp1bXB5ID4gMCk7CgoJICAgIGp1bXB4ID0gMDsKCSAgICBqdW1weS0tOwoKCSAgICAvKiBhZGQgRU9MIC0tIGVuZCBvZiBsaW5lICovCgkgICAgbHBiaU91dC0+YmlTaXplSW1hZ2UgKz0gMjsKCSAgICAqKChMUFdPUkQpbHBPdXQpID0gMDsKCSAgICBscE91dCArPSBzaXplb2YoV09SRCk7CgkgICAgYXNzZXJ0KGxwT3V0ID09IChscE91dFN0YXJ0ICsgbHBiaU91dC0+YmlTaXplSW1hZ2UpKTsKCSAgfQoKCSAgLyogRklYTUU6IGlmIChqdW1weSA9PSAwICYmIGNvdWxkIGVuY29kZSBhbGwpIHRoZW4ganVtcCB0b28gZXhwZW5zaXZlICovCgoJICAvKiB3cml0ZSBvdXQgcmVhbCBqdW1wKHMpICovCgkgIHdoaWxlIChqdW1weSB8fCBwb3MgIT0ganVtcHgpIHsKCSAgICBscGJpT3V0LT5iaVNpemVJbWFnZSArPSA0OwoJICAgICpscE91dCsrID0gMDsKCSAgICAqbHBPdXQrKyA9IDI7CgkgICAgKmxwT3V0ICAgPSBtaW4ocG9zIC0ganVtcHgsIDI1NSk7CgkgICAganVtcHggICArPSAqbHBPdXQrKzsKCSAgICAqbHBPdXQgICA9IG1pbihqdW1weSwgMjU1KTsKCSAgICBqdW1weSAgIC09ICpscE91dCsrOwoJICB9CgkgIHggPSBwb3M7CgoJICBqdW1weSA9IDA7Cgl9CgoJanVtcHggPSAtMTsKCglpZiAoeCA8IGxwYmlPdXQtPmJpV2lkdGgpIHsKCSAgLyogc2tpcCB0aGUgJ3NhbWUnIHRoaW5ncyBjb3JyZXNwb25kaW5nIHRvIHByZXZpb3VzIGZyYW1lICovCgkgIHggPSBNU1JMRTMyX0NvbXByZXNzUkxFOExpbmUocGksIGxwUCwgbHBDLCBscGJpSW4sIGxwSW4sIGxEaXN0LCB4LAoJCQkgICAgICAgJmxwT3V0LCAmbHBiaU91dC0+YmlTaXplSW1hZ2UpOwoJICBhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwoJfQogICAgICB9IHdoaWxlICh4IDwgbHBiaU91dC0+YmlXaWR0aCk7CgogICAgICBscFAgICs9IGxMaW5lOwogICAgICBscEMgICs9IGxMaW5lOwogICAgICBscEluICs9IGxJbkxpbmU7CgogICAgICBpZiAoanVtcHkgPT0gMCkgewoJLyogYWRkIEVPTCAtLSBlbmQgb2YgbGluZSAqLwoJbHBiaU91dC0+YmlTaXplSW1hZ2UgKz0gMjsKCSooKExQV09SRClscE91dCkgPSAwOwoJbHBPdXQgKz0gc2l6ZW9mKFdPUkQpOwoJYXNzZXJ0KGxwT3V0ID09IChscE91dFN0YXJ0ICsgbHBiaU91dC0+YmlTaXplSW1hZ2UpKTsKICAgICAgfQogICAgfQoKICAgIC8qIGFkZCBFT0wgLS0gd2lsbCBiZSBjaGFuZ2VkIHRvIEVPSSAqLwogICAgbHBiaU91dC0+YmlTaXplSW1hZ2UgKz0gMjsKICAgICooKExQV09SRClscE91dCkgPSAwOwogICAgbHBPdXQgKz0gc2l6ZW9mKFdPUkQpOwogIH0KCiAgLyogY2hhbmdlIEVPTCB0byBFT0kgLS0gZW5kIG9mIGltYWdlICovCiAgbHBPdXRbLTFdID0gMTsKICBhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfRGVjb21wcmVzc1JMRTQoY29uc3QgQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpLAoJCQkJICAgICAgY29uc3QgQllURSAqbHBJbiwgTFBCWVRFIGxwT3V0KQp7CiAgaW50ICBieXRlc19wZXJfcGl4ZWw7CiAgaW50ICBsaW5lX3NpemU7CiAgaW50ICBwaXhlbF9wdHIgID0gMDsKICBpbnQgIGk7CiAgQk9PTCBiRW5kRmxhZyAgID0gRkFMU0U7CgogIGFzc2VydChwaSAhPSBOVUxMKTsKICBhc3NlcnQobHBiaSAhPSBOVUxMICYmIGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCKTsKICBhc3NlcnQobHBJbiAhPSBOVUxMICYmIGxwT3V0ICE9IE5VTEwpOwoKICBieXRlc19wZXJfcGl4ZWwgPSAobHBiaS0+YmlCaXRDb3VudCArIDEpIC8gODsKICBsaW5lX3NpemUgICAgICAgPSBESUJXSURUSEJZVEVTKCpscGJpKTsKCiAgZG8gewogICAgQllURSBjb2RlMCwgY29kZTE7CgogICAgY29kZTAgPSAqbHBJbisrOwogICAgY29kZTEgPSAqbHBJbisrOwoKICAgIGlmIChjb2RlMCA9PSAwKSB7CiAgICAgIGludCAgZXh0cmFfYnl0ZTsKCiAgICAgIHN3aXRjaCAoY29kZTEpIHsKICAgICAgY2FzZSAgMDogLyogRU9MIC0gZW5kIG9mIGxpbmUgICovCglwaXhlbF9wdHIgPSAwOwoJbHBPdXQgKz0gbGluZV9zaXplOwoJYnJlYWs7CiAgICAgIGNhc2UgIDE6IC8qIEVPSSAtIGVuZCBvZiBpbWFnZSAqLwoJYkVuZEZsYWcgPSBUUlVFOwoJYnJlYWs7CiAgICAgIGNhc2UgIDI6IC8qIHNraXAgKi8KCXBpeGVsX3B0ciArPSAqbHBJbisrICogYnl0ZXNfcGVyX3BpeGVsOwoJbHBPdXQgICAgICs9ICpscEluKysgKiBsaW5lX3NpemU7CglpZiAocGl4ZWxfcHRyID49IGxwYmktPmJpV2lkdGggKiBieXRlc19wZXJfcGl4ZWwpIHsKCSAgcGl4ZWxfcHRyID0gMDsKCSAgbHBPdXQgICAgKz0gbGluZV9zaXplOwoJfQoJYnJlYWs7CiAgICAgIGRlZmF1bHQ6IC8qIGFic29sdXRlIG1vZGUgKi8KCWV4dHJhX2J5dGUgPSAoKChjb2RlMSArIDEpICYgKH4xKSkgLyAyKSAmIDB4MDE7CgoJaWYgKHBpeGVsX3B0ci9ieXRlc19wZXJfcGl4ZWwgKyBjb2RlMSA+IGxwYmktPmJpV2lkdGgpCgkgIHJldHVybiBJQ0VSUl9FUlJPUjsKCgljb2RlMCA9IGNvZGUxOwoJZm9yIChpID0gMDsgaSA8IGNvZGUwIC8gMjsgaSsrKSB7CgkgIGlmIChieXRlc19wZXJfcGl4ZWwgPT0gMSkgewoJICAgIGNvZGUxID0gbHBJbltpXTsKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpXTsKCSAgICBpZiAoMiAqIGkgKyAxIDw9IGNvZGUwKQoJICAgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSAmIDB4MEYpXTsKCSAgfSBlbHNlIGlmIChieXRlc19wZXJfcGl4ZWwgPT0gMikgewoJICAgIGNvZGUxID0gbHBJbltpXSA+PiA0OwoJICAgIGxwT3V0W3BpeGVsX3B0cisrXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDIgKyAwXTsKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMV07CgoJICAgIGlmICgyICogaSArIDEgPD0gY29kZTApIHsKCSAgICAgIGNvZGUxID0gbHBJbltpXSAmIDB4MEY7CgkgICAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMF07CgkgICAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMV07CgkgICAgfQoJICB9IGVsc2UgewoJICAgIGNvZGUxID0gbHBJbltpXSA+PiA0OwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDBdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDBdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDFdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDJdOwoJICAgIHBpeGVsX3B0ciArPSBieXRlc19wZXJfcGl4ZWw7CgoJICAgIGlmICgyICogaSArIDEgPD0gY29kZTApIHsKCSAgICAgIGNvZGUxID0gbHBJbltpXSAmIDB4MEY7CgkgICAgICBscE91dFtwaXhlbF9wdHIgKyAwXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAwXTsKCSAgICAgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDFdOwoJICAgICAgbHBPdXRbcGl4ZWxfcHRyICsgMl0gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiA0ICsgMl07CgkgICAgICBwaXhlbF9wdHIgKz0gYnl0ZXNfcGVyX3BpeGVsOwoJICAgIH0KCSAgfQoJfQoJaWYgKGNvZGUwICYgMHgwMSkgewoJICBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDEpIHsKCSAgICBjb2RlMSA9IGxwSW5baV07CgkgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSA+PiA0KV07CgkgIH0gZWxzZSBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDIpIHsKCSAgICBjb2RlMSA9IGxwSW5baV0gPj4gNDsKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMF07CgkgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogMiArIDFdOwoJICB9IGVsc2UgewoJICAgIGNvZGUxID0gbHBJbltpXSA+PiA0OwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDBdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDBdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDFdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDJdOwoJICAgIHBpeGVsX3B0ciArPSBieXRlc19wZXJfcGl4ZWw7CgkgIH0KCSAgbHBJbisrOwoJfQoJbHBJbiArPSBjb2RlMCAvIDI7CgoJLyogaWYgdGhlIFJMRSBjb2RlIGlzIG9kZCwgc2tpcCBhIGJ5dGUgaW4gdGhlIHN0cmVhbSAqLwoJaWYgKGV4dHJhX2J5dGUpCgkgIGxwSW4rKzsKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGNvZGVkIG1vZGUgKi8KICAgICAgaWYgKHBpeGVsX3B0ci9ieXRlc19wZXJfcGl4ZWwgKyBjb2RlMCA+IGxwYmktPmJpV2lkdGgpCglyZXR1cm4gSUNFUlJfRVJST1I7CgogICAgICBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDEpIHsKCUJZVEUgYzEgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpXTsKCUJZVEUgYzIgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxICYgMHgwRildOwoKCWZvciAoaSA9IDA7IGkgPCBjb2RlMDsgaSsrKSB7CgkgIGlmICgoaSAmIDEpID09IDApCgkgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gYzE7CgkgIGVsc2UKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBjMjsKCX0KICAgICAgfSBlbHNlIGlmIChieXRlc19wZXJfcGl4ZWwgPT0gMikgewoJQllURSBoaTEgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpICogMiArIDBdOwoJQllURSBsbzEgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpICogMiArIDFdOwoKCUJZVEUgaGkyID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSAmIDB4MEYpICogMiArIDBdOwoJQllURSBsbzIgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxICYgMHgwRikgKiAyICsgMV07CgoJZm9yIChpID0gMDsgaSA8IGNvZGUwOyBpKyspIHsKCSAgaWYgKChpICYgMSkgPT0gMCkgewoJICAgIGxwT3V0W3BpeGVsX3B0cisrXSA9IGhpMTsKCSAgICBscE91dFtwaXhlbF9wdHIrK10gPSBsbzE7CgkgIH0gZWxzZSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyKytdID0gaGkyOwoJICAgIGxwT3V0W3BpeGVsX3B0cisrXSA9IGxvMjsKCSAgfQoJfQogICAgICB9IGVsc2UgewoJQllURSBiMSA9IHBpLT5wYWxldHRlX21hcFsoY29kZTEgPj4gNCkgKiA0ICsgMF07CglCWVRFIGcxID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSA+PiA0KSAqIDQgKyAxXTsKCUJZVEUgcjEgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxID4+IDQpICogNCArIDJdOwoKCUJZVEUgYjIgPSBwaS0+cGFsZXR0ZV9tYXBbKGNvZGUxICYgMHgwRikgKiA0ICsgMF07CglCWVRFIGcyID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSAmIDB4MEYpICogNCArIDFdOwoJQllURSByMiA9IHBpLT5wYWxldHRlX21hcFsoY29kZTEgJiAweDBGKSAqIDQgKyAyXTsKCglmb3IgKGkgPSAwOyBpIDwgY29kZTA7IGkrKykgewoJICBpZiAoKGkgJiAxKSA9PSAwKSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyICsgMF0gPSBiMTsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IGcxOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcjE7CgkgIH0gZWxzZSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyICsgMF0gPSBiMjsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IGcyOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcjI7CgkgIH0KCSAgcGl4ZWxfcHRyICs9IGJ5dGVzX3Blcl9waXhlbDsKCX0KICAgICAgfQogICAgfQogIH0gd2hpbGUgKCEgYkVuZEZsYWcpOwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfRGVjb21wcmVzc1JMRTgoY29uc3QgQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpLAoJCQkJICAgICAgY29uc3QgQllURSAqbHBJbiwgTFBCWVRFIGxwT3V0KQp7CiAgaW50ICBieXRlc19wZXJfcGl4ZWw7CiAgaW50ICBsaW5lX3NpemU7CiAgaW50ICBwaXhlbF9wdHIgID0gMDsKICBCT09MIGJFbmRGbGFnICAgPSBGQUxTRTsKCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwogIGFzc2VydChscGJpICE9IE5VTEwgJiYgbHBiaS0+YmlDb21wcmVzc2lvbiA9PSBCSV9SR0IpOwogIGFzc2VydChscEluICE9IE5VTEwgJiYgbHBPdXQgIT0gTlVMTCk7CgogIGJ5dGVzX3Blcl9waXhlbCA9IChscGJpLT5iaUJpdENvdW50ICsgMSkgLyA4OwogIGxpbmVfc2l6ZSAgICAgICA9IERJQldJRFRIQllURVMoKmxwYmkpOwoKICBkbyB7CiAgICBCWVRFIGNvZGUwLCBjb2RlMTsKCiAgICBjb2RlMCA9ICpscEluKys7CiAgICBjb2RlMSA9ICpscEluKys7CgogICAgaWYgKGNvZGUwID09IDApIHsKICAgICAgaW50ICBleHRyYV9ieXRlOwoKICAgICAgc3dpdGNoIChjb2RlMSkgewogICAgICBjYXNlICAwOiAvKiBFT0wgLSBlbmQgb2YgbGluZSAgKi8KCXBpeGVsX3B0ciA9IDA7CglscE91dCArPSBsaW5lX3NpemU7CglicmVhazsKICAgICAgY2FzZSAgMTogLyogRU9JIC0gZW5kIG9mIGltYWdlICovCgliRW5kRmxhZyA9IFRSVUU7CglicmVhazsKICAgICAgY2FzZSAgMjogLyogc2tpcCAqLwoJcGl4ZWxfcHRyICs9ICpscEluKysgKiBieXRlc19wZXJfcGl4ZWw7CglscE91dCAgICAgKz0gKmxwSW4rKyAqIGxpbmVfc2l6ZTsKCWlmIChwaXhlbF9wdHIgPj0gbHBiaS0+YmlXaWR0aCAqIGJ5dGVzX3Blcl9waXhlbCkgewoJICBwaXhlbF9wdHIgPSAwOwoJICBscE91dCAgICArPSBsaW5lX3NpemU7Cgl9CglicmVhazsKICAgICAgZGVmYXVsdDogLyogYWJzb2x1dGUgbW9kZSAqLwoJaWYgKHBpeGVsX3B0ci9ieXRlc19wZXJfcGl4ZWwgKyBjb2RlMSA+IGxwYmktPmJpV2lkdGgpIHsKICAgICAgICAgIFdBUk4oImFib3J0ZWQgYWJzb2x1dGU6ICglZD0lZC8lZCslZCkgPiAlZFxuIixwaXhlbF9wdHIvYnl0ZXNfcGVyX3BpeGVsICsgY29kZTEscGl4ZWxfcHRyLGJ5dGVzX3Blcl9waXhlbCxjb2RlMSxscGJpLT5iaVdpZHRoKTsKCSAgcmV0dXJuIElDRVJSX0VSUk9SOwoJfQoJZXh0cmFfYnl0ZSA9IGNvZGUxICYgMHgwMTsKCgljb2RlMCA9IGNvZGUxOwoJd2hpbGUgKGNvZGUwLS0pIHsKCSAgY29kZTEgPSAqbHBJbisrOwoJICBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDEpIHsKCSAgICBscE91dFtwaXhlbF9wdHJdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxXTsKCSAgfSBlbHNlIGlmIChieXRlc19wZXJfcGl4ZWwgPT0gMikgewoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDBdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogMiArIDBdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogMiArIDFdOwoJICB9IGVsc2UgewoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDBdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDBdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDFdOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogNCArIDJdOwoJICB9CgkgIHBpeGVsX3B0ciArPSBieXRlc19wZXJfcGl4ZWw7Cgl9CgoJLyogaWYgdGhlIFJMRSBjb2RlIGlzIG9kZCwgc2tpcCBhIGJ5dGUgaW4gdGhlIHN0cmVhbSAqLwoJaWYgKGV4dHJhX2J5dGUpCgkgIGxwSW4rKzsKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIC8qIGNvZGVkIG1vZGUgKi8KICAgICAgaWYgKHBpeGVsX3B0ci9ieXRlc19wZXJfcGl4ZWwgKyBjb2RlMCA+IGxwYmktPmJpV2lkdGgpIHsKCVdBUk4oImFib3J0ZWQgY29kZWQ6ICglZD0lZC8lZCslZCkgPiAlZFxuIixwaXhlbF9wdHIvYnl0ZXNfcGVyX3BpeGVsICsgY29kZTEscGl4ZWxfcHRyLGJ5dGVzX3Blcl9waXhlbCxjb2RlMSxscGJpLT5iaVdpZHRoKTsKCXJldHVybiBJQ0VSUl9FUlJPUjsKICAgICAgfQoKICAgICAgaWYgKGJ5dGVzX3Blcl9waXhlbCA9PSAxKSB7Cgljb2RlMSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMV07Cgl3aGlsZSAoY29kZTAtLSkKCSAgbHBPdXRbcGl4ZWxfcHRyKytdID0gY29kZTE7CiAgICAgIH0gZWxzZSBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDIpIHsKCUJZVEUgaGkgPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMF07CglCWVRFIGxvID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxICogMiArIDFdOwoKCXdoaWxlIChjb2RlMC0tKSB7CgkgIGxwT3V0W3BpeGVsX3B0ciArIDBdID0gaGk7CgkgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gbG87CgkgIHBpeGVsX3B0ciArPSBieXRlc19wZXJfcGl4ZWw7Cgl9CiAgICAgIH0gZWxzZSB7CglCWVRFIHIgPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiA0ICsgMl07CglCWVRFIGcgPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiA0ICsgMV07CglCWVRFIGIgPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiA0ICsgMF07CgoJd2hpbGUgKGNvZGUwLS0pIHsKCSAgbHBPdXRbcGl4ZWxfcHRyICsgMF0gPSBiOwoJICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IGc7CgkgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcjsKCSAgcGl4ZWxfcHRyICs9IGJ5dGVzX3Blcl9waXhlbDsKCX0KICAgICAgfQogICAgfQogIH0gd2hpbGUgKCEgYkVuZEZsYWcpOwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBDb2RlY0luZm8qIE9wZW4oTFBJQ09QRU4gaWNpbmZvKQp7CiAgQ29kZWNJbmZvKiBwaSA9IE5VTEw7CgogIGlmIChpY2luZm8gPT0gTlVMTCkgewogICAgVFJBQ0UoIihOVUxMKVxuIik7CiAgICByZXR1cm4gKExQVk9JRCkweEZGRkYwMDAwOwogIH0KCiAgaWYgKGljaW5mby0+ZmNjVHlwZSAhPSBJQ1RZUEVfVklERU8pIHJldHVybiBOVUxMOwoKICBUUkFDRSgiKCVwID0geyV1LDB4JTA4WCglNC40cyksMHglMDhYKCU0LjRzKSwweCVYLDB4JVgsLi4ufSlcbiIsIGljaW5mbywKCWljaW5mby0+ZHdTaXplLAlpY2luZm8tPmZjY1R5cGUsIChjaGFyKikmaWNpbmZvLT5mY2NUeXBlLAoJaWNpbmZvLT5mY2NIYW5kbGVyLCAoY2hhciopJmljaW5mby0+ZmNjSGFuZGxlciwKCWljaW5mby0+ZHdWZXJzaW9uLGljaW5mby0+ZHdGbGFncyk7CgogIHN3aXRjaCAoaWNpbmZvLT5mY2NIYW5kbGVyKSB7CiAgY2FzZSBGT1VSQ0NfUkxFOgogIGNhc2UgRk9VUkNDX1JMRTQ6CiAgY2FzZSBGT1VSQ0NfUkxFODoKICBjYXNlIEZPVVJDQ19NUkxFOgogICAgYnJlYWs7CiAgY2FzZSBtbWlvRk9VUkNDKCdtJywncicsJ2wnLCdlJyk6CiAgICBpY2luZm8tPmZjY0hhbmRsZXIgPSBGT1VSQ0NfTVJMRTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBXQVJOKCJ1bmtub3duIEZPVVJDQyA9IDB4JTA4WCglNC40cykgIVxuIiwKCSBpY2luZm8tPmZjY0hhbmRsZXIsKGNoYXIqKSZpY2luZm8tPmZjY0hhbmRsZXIpOwogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBwaSA9IChDb2RlY0luZm8qKUxvY2FsQWxsb2MoTFBUUiwgc2l6ZW9mKENvZGVjSW5mbykpOwoKICBpZiAocGkgIT0gTlVMTCkgewogICAgcGktPmZjY0hhbmRsZXIgID0gaWNpbmZvLT5mY2NIYW5kbGVyOwoKICAgIHBpLT5iQ29tcHJlc3MgICA9IEZBTFNFOwogICAgcGktPmR3UXVhbGl0eSAgID0gTVNSTEUzMl9ERUZBVUxUUVVBTElUWTsKICAgIHBpLT5uUHJldkZyYW1lICA9IC0xOwogICAgcGktPnBQcmV2RnJhbWUgID0gcGktPnBDdXJGcmFtZSA9IE5VTEw7CgogICAgcGktPmJEZWNvbXByZXNzID0gRkFMU0U7CiAgICBwaS0+cGFsZXR0ZV9tYXAgPSBOVUxMOwogIH0KCiAgaWNpbmZvLT5kd0Vycm9yID0gKHBpICE9IE5VTEwgPyBJQ0VSUl9PSyA6IElDRVJSX01FTU9SWSk7CgogIHJldHVybiBwaTsKfQoKc3RhdGljIExSRVNVTFQgQ2xvc2UoQ29kZWNJbmZvICpwaSkKewogIFRSQUNFKCIoJXApXG4iLCBwaSk7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIGlmIChwaS0+cFByZXZGcmFtZSAhPSBOVUxMIHx8IHBpLT5wQ3VyRnJhbWUgIT0gTlVMTCkKICAgIENvbXByZXNzRW5kKHBpKTsKCiAgTG9jYWxGcmVlKChITE9DQUwpcGkpOwogIHJldHVybiAxOwp9CgpzdGF0aWMgTFJFU1VMVCBHZXRJbmZvKGNvbnN0IENvZGVjSW5mbyAqcGksIElDSU5GTyAqaWNpbmZvLCBEV09SRCBkd1NpemUpCnsKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGljaW5mbyA9PSBOVUxMKQogICAgcmV0dXJuIHNpemVvZihJQ0lORk8pOwogIGlmIChkd1NpemUgPCBzaXplb2YoSUNJTkZPKSkKICAgIHJldHVybiAwOwoKICBpY2luZm8tPmR3U2l6ZSAgICAgICA9IHNpemVvZihJQ0lORk8pOwogIGljaW5mby0+ZmNjVHlwZSAgICAgID0gSUNUWVBFX1ZJREVPOwogIGljaW5mby0+ZmNjSGFuZGxlciAgID0gKHBpICE9IE5VTEwgPyBwaS0+ZmNjSGFuZGxlciA6IEZPVVJDQ19NUkxFKTsKICBpY2luZm8tPmR3RmxhZ3MgICAgICA9IFZJRENGX1FVQUxJVFkgfCBWSURDRl9URU1QT1JBTCB8IFZJRENGX0NSVU5DSCB8IFZJRENGX0ZBU1RURU1QT1JBTEM7CiAgaWNpbmZvLT5kd1ZlcnNpb24gICAgPSBJQ1ZFUlNJT047CiAgaWNpbmZvLT5kd1ZlcnNpb25JQ00gPSBJQ1ZFUlNJT047CgogIExvYWRTdHJpbmdXKE1TUkxFMzJfaE1vZHVsZSwgSURTX05BTUUsIGljaW5mby0+c3pOYW1lLCBzaXplb2YoaWNpbmZvLT5zek5hbWUpL3NpemVvZihXQ0hBUikpOwogIExvYWRTdHJpbmdXKE1TUkxFMzJfaE1vZHVsZSwgSURTX0RFU0NSSVBUSU9OLCBpY2luZm8tPnN6RGVzY3JpcHRpb24sIHNpemVvZihpY2luZm8tPnN6RGVzY3JpcHRpb24pL3NpemVvZihXQ0hBUikpOwoKICByZXR1cm4gc2l6ZW9mKElDSU5GTyk7Cn0KCnN0YXRpYyBMUkVTVUxUIFNldFF1YWxpdHkoQ29kZWNJbmZvICpwaSwgTE9ORyBsUXVhbGl0eSkKewogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIGlmIChsUXVhbGl0eSA9PSAtMSkKICAgIGxRdWFsaXR5ID0gTVNSTEUzMl9ERUZBVUxUUVVBTElUWTsKICBlbHNlIGlmIChJQ1FVQUxJVFlfTE9XID4gbFF1YWxpdHkgfHwgbFF1YWxpdHkgPiBJQ1FVQUxJVFlfSElHSCkKICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKCiAgcGktPmR3UXVhbGl0eSA9IChEV09SRClsUXVhbGl0eTsKCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb25maWd1cmUoY29uc3QgQ29kZWNJbmZvICpwaSwgSFdORCBoV25kKQp7CiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgLyogRklYTUUgKi8KICByZXR1cm4gSUNFUlJfT0s7Cn0KCnN0YXRpYyBMUkVTVUxUIEFib3V0KENvZGVjSW5mbyAqcGksIEhXTkQgaFduZCkKewogIFdDSEFSIHN6VGl0bGVbMjBdOwogIFdDSEFSIHN6QWJvdXRbMTI4XTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChNU1JMRTMyX2hNb2R1bGUgIT0gMCk7CgogIExvYWRTdHJpbmdXKE1TUkxFMzJfaE1vZHVsZSwgSURTX05BTUUsIHN6VGl0bGUsIHNpemVvZihzelRpdGxlKSk7CiAgTG9hZFN0cmluZ1coTVNSTEUzMl9oTW9kdWxlLCBJRFNfQUJPVVQsIHN6QWJvdXQsIHNpemVvZihzekFib3V0KSk7CgogIE1lc3NhZ2VCb3hXKGhXbmQsIHN6QWJvdXQsIHN6VGl0bGUsIE1CX09LfE1CX0lDT05JTkZPUk1BVElPTik7CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKc3RhdGljIExSRVNVTFQgQ29tcHJlc3NHZXRGb3JtYXQoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCQkgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpCnsKICBMUkVTVUxUIHNpemU7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLHBpLGxwYmlJbixscGJpT3V0KTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAtLSBuZWVkIGF0IGxlYXN0IGlucHV0IGZvcm1hdCAqLwogIGlmIChscGJpSW4gPT0gTlVMTCkgewogICAgaWYgKGxwYmlPdXQgIT0gTlVMTCkKICAgICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwogICAgcmV0dXJuIDA7CiAgfQoKICAvKiBoYW5kbGUgdW5zdXBwb3J0ZWQgaW5wdXQgZm9ybWF0ICovCiAgaWYgKENvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgTlVMTCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gKGxwYmlPdXQgPT0gTlVMTCA/IElDRVJSX0JBREZPUk1BVCA6IDApOwoKICBhc3NlcnQoMCA8IGxwYmlJbi0+YmlCaXRDb3VudCAmJiBscGJpSW4tPmJpQml0Q291bnQgPD0gOCk7CgogIHN3aXRjaCAocGktPmZjY0hhbmRsZXIpIHsKICBjYXNlIEZPVVJDQ19STEU0OgogICAgc2l6ZSA9IDEgPDwgNDsKICAgIGJyZWFrOwogIGNhc2UgRk9VUkNDX1JMRTg6CiAgICBzaXplID0gMSA8PCA4OwogICAgYnJlYWs7CiAgY2FzZSBGT1VSQ0NfUkxFOgogIGNhc2UgRk9VUkNDX01STEU6CiAgICBzaXplID0gKGxwYmlJbi0+YmlCaXRDb3VudCA8PSA0ID8gMSA8PCA0IDogMSA8PCA4KTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gSUNFUlJfRVJST1I7CiAgfQoKICBpZiAobHBiaUluLT5iaUNsclVzZWQgIT0gMCkKICAgIHNpemUgPSBscGJpSW4tPmJpQ2xyVXNlZDsKCiAgc2l6ZSA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSArIHNpemUgKiBzaXplb2YoUkdCUVVBRCk7CgogIGlmIChscGJpT3V0ICE9IE5VTEwpIHsKICAgIGxwYmlPdXQtPmJpU2l6ZSAgICAgICAgICA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKTsKICAgIGxwYmlPdXQtPmJpV2lkdGggICAgICAgICA9IGxwYmlJbi0+YmlXaWR0aDsKICAgIGxwYmlPdXQtPmJpSGVpZ2h0ICAgICAgICA9IGxwYmlJbi0+YmlIZWlnaHQ7CiAgICBscGJpT3V0LT5iaVBsYW5lcyAgICAgICAgPSAxOwogICAgaWYgKHBpLT5mY2NIYW5kbGVyID09IEZPVVJDQ19STEU0IHx8CglscGJpSW4tPmJpQml0Q291bnQgPD0gNCkgewogICAgICBscGJpT3V0LT5iaUNvbXByZXNzaW9uID0gQklfUkxFNDsKICAgICAgbHBiaU91dC0+YmlCaXRDb3VudCAgICA9IDQ7CiAgICB9IGVsc2UgewogICAgICBscGJpT3V0LT5iaUNvbXByZXNzaW9uID0gQklfUkxFODsKICAgICAgbHBiaU91dC0+YmlCaXRDb3VudCAgICA9IDg7CiAgICB9CiAgICBscGJpT3V0LT5iaVNpemVJbWFnZSAgICAgPSBNU1JMRTMyX0dldE1heENvbXByZXNzZWRTaXplKGxwYmlPdXQpOwogICAgbHBiaU91dC0+YmlYUGVsc1Blck1ldGVyID0gbHBiaUluLT5iaVhQZWxzUGVyTWV0ZXI7CiAgICBscGJpT3V0LT5iaVlQZWxzUGVyTWV0ZXIgPSBscGJpSW4tPmJpWVBlbHNQZXJNZXRlcjsKICAgIGlmIChscGJpSW4tPmJpQ2xyVXNlZCA9PSAwKQogICAgICBzaXplID0gMTw8bHBiaUluLT5iaUJpdENvdW50OwogICAgZWxzZQogICAgICBzaXplID0gbHBiaUluLT5iaUNsclVzZWQ7CiAgICBscGJpT3V0LT5iaUNsclVzZWQgICAgICAgPSBtaW4oc2l6ZSwgMSA8PCBscGJpT3V0LT5iaUJpdENvdW50KTsKICAgIGxwYmlPdXQtPmJpQ2xySW1wb3J0YW50ICA9IDA7CgogICAgbWVtY3B5KChMUEJZVEUpbHBiaU91dCArIGxwYmlPdXQtPmJpU2l6ZSwKCSAgIChjb25zdCBCWVRFKilscGJpSW4gKyBscGJpSW4tPmJpU2l6ZSwgbHBiaU91dC0+YmlDbHJVc2VkICogc2l6ZW9mKFJHQlFVQUQpKTsKCiAgICByZXR1cm4gSUNFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIExSRVNVTFQgQ29tcHJlc3NHZXRTaXplKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KQp7CiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXIgLS0gbmVlZCBhdCBsZWFzdCBvbmUgZm9ybWF0ICovCiAgaWYgKGxwYmlJbiA9PSBOVUxMICYmIGxwYmlPdXQgPT0gTlVMTCkKICAgIHJldHVybiAwOwogIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBmb3JtYXQgaXMgc3VwcG9ydGVkICovCiAgaWYgKENvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgbHBiaU91dCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gMDsKCiAgLyogdGhlIHdvcnN0IGNhc2UgaXMgY29kaW5nIHRoZSBjb21wbGV0ZSBpbWFnZSBpbiBhYnNvbHV0ZSBtb2RlLiAqLwogIGlmIChscGJpSW4pCiAgICByZXR1cm4gTVNSTEUzMl9HZXRNYXhDb21wcmVzc2VkU2l6ZShscGJpSW4pOwogIGVsc2UKICAgIHJldHVybiBNU1JMRTMyX0dldE1heENvbXByZXNzZWRTaXplKGxwYmlPdXQpOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc1F1ZXJ5KGNvbnN0IENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIG5lZWQgYXQgbGVhc3Qgb25lIGZvcm1hdCAqLwogIGlmIChscGJpSW4gPT0gTlVMTCAmJiBscGJpT3V0ID09IE5VTEwpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CgogIC8qIGNoZWNrIGlucHV0IGZvcm1hdCBpZiBnaXZlbiAqLwogIGlmIChscGJpSW4gIT0gTlVMTCkgewogICAgaWYgKCFpc1N1cHBvcnRlZERJQihscGJpSW4pKQogICAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwoKICAgIC8qIGZvciA0LWJpdCBuZWVkIGFuIGV2ZW4gd2lkdGggKi8KICAgIGlmIChscGJpSW4tPmJpQml0Q291bnQgPD0gNCAmJiAobHBiaUluLT5iaVdpZHRoICUgMikpCiAgICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CgogICAgaWYgKHBpLT5mY2NIYW5kbGVyID09IEZPVVJDQ19STEU0ICYmIGxwYmlJbi0+YmlCaXRDb3VudCA+IDQpCiAgICAgIHJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsKICAgIGVsc2UgaWYgKGxwYmlJbi0+YmlCaXRDb3VudCA+IDgpCiAgICAgIHJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIGNoZWNrIG91dHB1dCBmb3JtYXQgaWYgZ2l2ZW4gKi8KICBpZiAobHBiaU91dCAhPSBOVUxMKSB7CiAgICBpZiAoIWlzU3VwcG9ydGVkTVJMRShscGJpT3V0KSkKICAgICAgcmV0dXJuIElDRVJSX0JBREZPUk1BVDsKCiAgICBpZiAobHBiaUluICE9IE5VTEwpIHsKICAgICAgaWYgKGxwYmlJbi0+YmlXaWR0aCAgIT0gbHBiaU91dC0+YmlXaWR0aCkKCXJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsKICAgICAgaWYgKGxwYmlJbi0+YmlIZWlnaHQgIT0gbHBiaU91dC0+YmlIZWlnaHQpCglyZXR1cm4gSUNFUlJfVU5TVVBQT1JURUQ7CiAgICAgIGlmIChscGJpSW4tPmJpQml0Q291bnQgPiBscGJpT3V0LT5iaUJpdENvdW50KQoJcmV0dXJuIElDRVJSX1VOU1VQUE9SVEVEOwogICAgfQogIH0KCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0JlZ2luKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIGNvbnN0IFJHQlFVQUQgKnJnYkluOwogIGNvbnN0IFJHQlFVQUQgKnJnYk91dDsKICBVSU5UICAgaTsKICBzaXplX3Qgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzIC0tIG5lZWQgYm90aCBmb3JtYXRzICovCiAgaWYgKGxwYmlJbiA9PSBOVUxMIHx8IGxwYmlPdXQgPT0gTlVMTCkKICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKICAvKiBBbmQgYm90aCBtdXN0IGJlIHN1cHBvcnRlZCAqLwogIGlmIChDb21wcmVzc1F1ZXJ5KHBpLCBscGJpSW4sIGxwYmlPdXQpICE9IElDRVJSX09LKQogICAgcmV0dXJuIElDRVJSX0JBREZPUk1BVDsKCiAgLyogRklYTUU6IGNhbm5vdCBjb21wcmVzcyBhbmQgZGVjb21wcmVzcyBhdCBzYW1lIHRpbWUhICovCiAgaWYgKHBpLT5iRGVjb21wcmVzcykgewogICAgRklYTUUoImNhbm5vdCBjb21wcmVzcyBhbmQgZGVjb21wcmVzcyBhdCBzYW1lIHRpbWUhXG4iKTsKICAgIHJldHVybiBJQ0VSUl9FUlJPUjsKICB9CgogIGlmIChwaS0+YkNvbXByZXNzKQogICAgQ29tcHJlc3NFbmQocGkpOwoKICBzaXplID0gV0lEVEhCWVRFUyhscGJpT3V0LT5iaVdpZHRoICogMTYpIC8gMiAqIGxwYmlPdXQtPmJpSGVpZ2h0OwogIHBpLT5wUHJldkZyYW1lID0gR2xvYmFsTG9jayhHbG9iYWxBbGxvYyhHUFRSLCBzaXplICogc2l6ZW9mKFdPUkQpKSk7CiAgaWYgKHBpLT5wUHJldkZyYW1lID09IE5VTEwpCiAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwogIHBpLT5wQ3VyRnJhbWUgPSBHbG9iYWxMb2NrKEdsb2JhbEFsbG9jKEdQVFIsIHNpemUgKiBzaXplb2YoV09SRCkpKTsKICBpZiAocGktPnBDdXJGcmFtZSA9PSBOVUxMKSB7CiAgICBDb21wcmVzc0VuZChwaSk7CiAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwogIH0KICBwaS0+blByZXZGcmFtZSA9IC0xOwogIHBpLT5iQ29tcHJlc3MgID0gVFJVRTsKCiAgcmdiSW4gID0gKGNvbnN0IFJHQlFVQUQqKSgoY29uc3QgQllURSopbHBiaUluICArIGxwYmlJbi0+YmlTaXplKTsKICByZ2JPdXQgPSAoY29uc3QgUkdCUVVBRCopKChjb25zdCBCWVRFKilscGJpT3V0ICsgbHBiaU91dC0+YmlTaXplKTsKCiAgc3dpdGNoIChscGJpT3V0LT5iaUJpdENvdW50KSB7CiAgY2FzZSA0OgogIGNhc2UgODoKICAgIHBpLT5wYWxldHRlX21hcCA9IChMUEJZVEUpTG9jYWxBbGxvYyhMUFRSLCBscGJpSW4tPmJpQ2xyVXNlZCk7CiAgICBpZiAocGktPnBhbGV0dGVfbWFwID09IE5VTEwpIHsKICAgICAgQ29tcHJlc3NFbmQocGkpOwogICAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBscGJpSW4tPmJpQ2xyVXNlZDsgaSsrKSB7CiAgICAgIHBpLT5wYWxldHRlX21hcFtpXSA9IE1TUkxFMzJfR2V0TmVhcmVzdFBhbGV0dGVJbmRleChscGJpT3V0LT5iaUNsclVzZWQsIHJnYk91dCwgcmdiSW5baV0pOwogICAgfQogICAgYnJlYWs7CiAgfTsKCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzcyhDb2RlY0luZm8gKnBpLCBJQ0NPTVBSRVNTKiBscGljLCBEV09SRCBkd1NpemUpCnsKICBpbnQgaTsKCiAgVFJBQ0UoIiglcCwlcCwldSlcbiIscGksbHBpYyxkd1NpemUpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwaWMgPT0gTlVMTCB8fCBkd1NpemUgPCBzaXplb2YoSUNDT01QUkVTUykpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CiAgaWYgKCFscGljLT5scGJpT3V0cHV0IHx8ICFscGljLT5scE91dHB1dCB8fAogICAgICAhbHBpYy0+bHBiaUlucHV0ICB8fCAhbHBpYy0+bHBJbnB1dCkKICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKCiAgVFJBQ0UoImxwaWM9ezB4JVgsJXAsJXAsJXAsJXAsJXAsJXAsJWQsJXUsJXUsJXAsJXB9XG4iLGxwaWMtPmR3RmxhZ3MsbHBpYy0+bHBiaU91dHB1dCxscGljLT5scE91dHB1dCxscGljLT5scGJpSW5wdXQsbHBpYy0+bHBJbnB1dCxscGljLT5scGNraWQsbHBpYy0+bHBkd0ZsYWdzLGxwaWMtPmxGcmFtZU51bSxscGljLT5kd0ZyYW1lU2l6ZSxscGljLT5kd1F1YWxpdHksbHBpYy0+bHBiaVByZXYsbHBpYy0+bHBQcmV2KTsKCiAgaWYgKCEgcGktPmJDb21wcmVzcykgewogICAgTFJFU1VMVCBociA9IENvbXByZXNzQmVnaW4ocGksIGxwaWMtPmxwYmlJbnB1dCwgbHBpYy0+bHBiaU91dHB1dCk7CiAgICBpZiAoaHIgIT0gSUNFUlJfT0spCiAgICAgIHJldHVybiBocjsKICB9IGVsc2UgaWYgKENvbXByZXNzUXVlcnkocGksIGxwaWMtPmxwYmlJbnB1dCwgbHBpYy0+bHBiaU91dHB1dCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwoKICBpZiAobHBpYy0+bEZyYW1lTnVtID49IHBpLT5uUHJldkZyYW1lICsgMSkgewogICAgLyogd2UgY29udGludWUgaW4gdGhlIHNlcXVlbmNlIHNvIHdlIG5lZWQgdG8gaW5pdGlhbGl6ZSAKICAgICAqIG91ciBpbnRlcm5hbCBmcmFtZWRhdGEgKi8KCiAgICBjb21wdXRlSW50ZXJuYWxGcmFtZShwaSwgbHBpYy0+bHBiaUlucHV0LCBscGljLT5scElucHV0KTsKICB9IGVsc2UgaWYgKGxwaWMtPmxGcmFtZU51bSA9PSBwaS0+blByZXZGcmFtZSkgewogICAgLyogT29wcywgY29tcHJlc3Mgc2FtZSBmcmFtZSBhZ2FpbiA/IE9rYXksIGFzIHlvdSB3aXNoLgogICAgICogTm8gbmVlZCB0byByZWNvbXB1dGUgaW50ZXJuYWwgZnJhbWVkYXRhLCBiZWNhdXNlIHdlIG9ubHkgc3dhcHBlZCBidWZmZXJzICovCiAgICBMUFdPUkQgcFRtcCA9IHBpLT5wUHJldkZyYW1lOwoKICAgIHBpLT5wUHJldkZyYW1lID0gcGktPnBDdXJGcmFtZTsKICAgIHBpLT5wQ3VyRnJhbWUgID0gcFRtcDsKICB9IGVsc2UgaWYgKChscGljLT5kd0ZsYWdzICYgSUNDT01QUkVTU19LRVlGUkFNRSkgPT0gMCkgewogICAgTFBXT1JEIHBUbXA7CgogICAgV0FSTigiOiBwcmV2PSVkIGN1cj0lZCBnb25lIGJhY2s/IC0tIHVudGVzdGVkXG4iLHBpLT5uUHJldkZyYW1lLGxwaWMtPmxGcmFtZU51bSk7CiAgICBpZiAobHBpYy0+bHBiaVByZXYgPT0gTlVMTCB8fCBscGljLT5scFByZXYgPT0gTlVMTCkKICAgICAgcmV0dXJuIElDRVJSX0dPVE9LRVlGUkFNRTsgLyogTmVlZCBhIGtleWZyYW1lIGlmIHlvdSBnbyBiYWNrICovCiAgICBpZiAoQ29tcHJlc3NRdWVyeShwaSwgbHBpYy0+bHBiaVByZXYsIGxwaWMtPmxwYmlPdXRwdXQpICE9IElDRVJSX09LKQogICAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwoKICAgIFdBUk4oIjogcHJldj0lZCBjdXI9JWQgY29tcHV0ZSBzd2FwcGVkIC0tIHVudGVzdGVkXG4iLHBpLT5uUHJldkZyYW1lLGxwaWMtPmxGcmFtZU51bSk7CiAgICBjb21wdXRlSW50ZXJuYWxGcmFtZShwaSwgbHBpYy0+bHBiaVByZXYsIGxwaWMtPmxwUHJldik7CgogICAgLyogc3dhcCBidWZmZXJzIGZvciBjdXJyZW50IGFuZCBwcmV2aW91cyBmcmFtZSAqLwogICAgLyogRG9uJ3QgZnJlZSBhbmQgYWxsb2MgbmV3IC0tIGNvc3RzIHRvIG11Y2ggdGltZSBhbmQgdGhleSBhcmUgb2YgZXF1YWwgc2l6ZSAhICovCiAgICBwVG1wID0gcGktPnBQcmV2RnJhbWU7CiAgICBwaS0+cFByZXZGcmFtZSA9IHBpLT5wQ3VyRnJhbWU7CiAgICBwaS0+cEN1ckZyYW1lICA9IHBUbXA7CiAgICBwaS0+blByZXZGcmFtZSA9IGxwaWMtPmxGcmFtZU51bTsKICB9CgogIGZvciAoaSA9IDA7IGkgPCAzOyBpKyspIHsKICAgIFNldFF1YWxpdHkocGksIGxwaWMtPmR3UXVhbGl0eSk7CgogICAgbHBpYy0+bHBiaU91dHB1dC0+YmlTaXplSW1hZ2UgPSAwOwoKICAgIGlmIChscGljLT5scGJpT3V0cHV0LT5iaUJpdENvdW50ID09IDQpCiAgICAgIE1TUkxFMzJfQ29tcHJlc3NSTEU0KHBpLCBscGljLT5scGJpSW5wdXQsIChMUEJZVEUpbHBpYy0+bHBJbnB1dCwKCQkgICBscGljLT5scGJpT3V0cHV0LCAoTFBCWVRFKWxwaWMtPmxwT3V0cHV0LCAobHBpYy0+ZHdGbGFncyAmIElDQ09NUFJFU1NfS0VZRlJBTUUpICE9IDApOwogICAgZWxzZQogICAgICBNU1JMRTMyX0NvbXByZXNzUkxFOChwaSwgbHBpYy0+bHBiaUlucHV0LCAoTFBCWVRFKWxwaWMtPmxwSW5wdXQsCgkJICAgbHBpYy0+bHBiaU91dHB1dCwgKExQQllURSlscGljLT5scE91dHB1dCwgKGxwaWMtPmR3RmxhZ3MgJiBJQ0NPTVBSRVNTX0tFWUZSQU1FKSAhPSAwKTsKCiAgICBpZiAobHBpYy0+ZHdGcmFtZVNpemUgPT0gMCB8fAoJbHBpYy0+bHBiaU91dHB1dC0+YmlTaXplSW1hZ2UgPCBscGljLT5kd0ZyYW1lU2l6ZSkKICAgICAgYnJlYWs7CgogICAgaWYgKCgqbHBpYy0+bHBkd0ZsYWdzICYgSUNDT01QUkVTU19LRVlGUkFNRSkgPT0gMCkgewogICAgICBpZiAobHBpYy0+bHBiaU91dHB1dC0+YmlCaXRDb3VudCA9PSA0KQoJTVNSTEUzMl9Db21wcmVzc1JMRTQocGksIGxwaWMtPmxwYmlJbnB1dCwgKExQQllURSlscGljLT5scElucHV0LAoJCQkgICAgIGxwaWMtPmxwYmlPdXRwdXQsIChMUEJZVEUpbHBpYy0+bHBPdXRwdXQsIFRSVUUpOwogICAgICBlbHNlCglNU1JMRTMyX0NvbXByZXNzUkxFOChwaSwgbHBpYy0+bHBiaUlucHV0LCAoTFBCWVRFKWxwaWMtPmxwSW5wdXQsCgkJCSAgICAgbHBpYy0+bHBiaU91dHB1dCwgKExQQllURSlscGljLT5scE91dHB1dCwgVFJVRSk7CgogICAgICBpZiAobHBpYy0+ZHdGcmFtZVNpemUgPT0gMCB8fAoJICBscGljLT5scGJpT3V0cHV0LT5iaVNpemVJbWFnZSA8IGxwaWMtPmR3RnJhbWVTaXplKSB7CglXQVJOKCJzd2l0Y2hlZCB0byBrZXlmcmFtZSwgd2FzIHNtYWxsIGVub3VnaCFcbiIpOwoJKmxwaWMtPmxwZHdGbGFncyB8PSBJQ0NPTVBSRVNTX0tFWUZSQU1FOwoJKmxwaWMtPmxwY2tpZCAgICA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmJpdHMsCgkJCQkgICAgICAgU3RyZWFtRnJvbUZPVVJDQygqbHBpYy0+bHBja2lkKSk7CglicmVhazsKICAgICAgfQogICAgfQoKICAgIGlmIChscGljLT5kd1F1YWxpdHkgPCAxMDAwKQogICAgICBicmVhazsKCiAgICBscGljLT5kd1F1YWxpdHkgLT0gMTAwMDsgLyogcmVkdWNlIHF1YWxpdHkgYnkgMTAlICovCiAgfQoKICB7IC8qIHN3YXAgYnVmZmVyIGZvciBjdXJyZW50IGFuZCBwcmV2aW91cyBmcmFtZSAqLwogICAgLyogRG9uJ3QgZnJlZSBhbmQgYWxsb2MgbmV3IC0tIGNvc3RzIHRvIG11Y2ggdGltZSBhbmQgdGhleSBhcmUgb2YgZXF1YWwgc2l6ZSAhICovCiAgICByZWdpc3RlciBMUFdPUkQgcFRtcCA9IHBpLT5wUHJldkZyYW1lOwoKICAgIHBpLT5wUHJldkZyYW1lID0gcGktPnBDdXJGcmFtZTsKICAgIHBpLT5wQ3VyRnJhbWUgID0gcFRtcDsKICAgIHBpLT5uUHJldkZyYW1lID0gbHBpYy0+bEZyYW1lTnVtOwogIH0KCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0VuZChDb2RlY0luZm8gKnBpKQp7CiAgVFJBQ0UoIiglcClcbiIscGkpOwoKICBpZiAocGkgIT0gTlVMTCkgewogICAgaWYgKHBpLT5wUHJldkZyYW1lICE9IE5VTEwpCiAgICB7CiAgICAgIEdsb2JhbFVubG9jayhHbG9iYWxIYW5kbGUocGktPnBQcmV2RnJhbWUpKTsKICAgICAgR2xvYmFsRnJlZShHbG9iYWxIYW5kbGUocGktPnBQcmV2RnJhbWUpKTsKICAgIH0KICAgIGlmIChwaS0+cEN1ckZyYW1lICE9IE5VTEwpCiAgICB7CiAgICAgIEdsb2JhbFVubG9jayhHbG9iYWxIYW5kbGUocGktPnBDdXJGcmFtZSkpOwogICAgICBHbG9iYWxGcmVlKEdsb2JhbEhhbmRsZShwaS0+cEN1ckZyYW1lKSk7CiAgICB9CiAgICBwaS0+cFByZXZGcmFtZSA9IE5VTEw7CiAgICBwaS0+cEN1ckZyYW1lICA9IE5VTEw7CiAgICBwaS0+blByZXZGcmFtZSA9IC0xOwogICAgcGktPmJDb21wcmVzcyAgPSBGQUxTRTsKICB9CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0dldEZvcm1hdChDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJCSAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KQp7CiAgRFdPUkQgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICBpZiAobHBiaUluID09IE5VTEwpCiAgICByZXR1cm4gKGxwYmlPdXQgIT0gTlVMTCA/IElDRVJSX0JBRFBBUkFNIDogMCk7CgogIGlmIChEZWNvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgTlVMTCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gKGxwYmlPdXQgIT0gTlVMTCA/IElDRVJSX0JBREZPUk1BVCA6IDApOwoKICBzaXplID0gbHBiaUluLT5iaVNpemU7CgogIGlmIChscGJpSW4tPmJpQml0Q291bnQgPD0gOCkKICAgIHNpemUgKz0gbHBiaUluLT5iaUNsclVzZWQgKiBzaXplb2YoUkdCUVVBRCk7CgogIGlmIChscGJpT3V0ICE9IE5VTEwpIHsKICAgIG1lbWNweShscGJpT3V0LCBscGJpSW4sIHNpemUpOwogICAgbHBiaU91dC0+YmlDb21wcmVzc2lvbiAgPSBCSV9SR0I7CiAgICBscGJpT3V0LT5iaVNpemVJbWFnZSAgICA9IERJQldJRFRIQllURVMoKmxwYmlPdXQpICogbHBiaU91dC0+YmlIZWlnaHQ7CgogICAgcmV0dXJuIElDRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIHNpemU7Cn0KCnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NRdWVyeShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJICAgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIExSRVNVTFQgaHIgPSBJQ0VSUl9PSzsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBuZWVkIGF0IGxlYXN0IG9uZSBmb3JtYXQgKi8KICBpZiAobHBiaUluID09IE5VTEwgJiYgbHBiaU91dCA9PSBOVUxMKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwoKICAvKiBjaGVjayBpbnB1dCBmb3JtYXQgaWYgZ2l2ZW4gKi8KICBpZiAobHBiaUluICE9IE5VTEwpIHsKICAgIGlmICghaXNTdXBwb3J0ZWRNUkxFKGxwYmlJbikpCiAgICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CiAgfQoKICAvKiBjaGVjayBvdXRwdXQgZm9ybWF0IGlmIGdpdmVuICovCiAgaWYgKGxwYmlPdXQgIT0gTlVMTCkgewogICAgaWYgKCFpc1N1cHBvcnRlZERJQihscGJpT3V0KSkKICAgICAgaHIgPSBJQ0VSUl9CQURGT1JNQVQ7CgogICAgaWYgKGxwYmlJbiAhPSBOVUxMKSB7CiAgICAgIGlmIChscGJpSW4tPmJpV2lkdGggICE9IGxwYmlPdXQtPmJpV2lkdGgpCglociA9IElDRVJSX1VOU1VQUE9SVEVEOwogICAgICBpZiAobHBiaUluLT5iaUhlaWdodCAhPSBscGJpT3V0LT5iaUhlaWdodCkKCWhyID0gSUNFUlJfVU5TVVBQT1JURUQ7CiAgICAgIGlmIChscGJpSW4tPmJpQml0Q291bnQgPiBscGJpT3V0LT5iaUJpdENvdW50KQoJaHIgPSBJQ0VSUl9VTlNVUFBPUlRFRDsKICAgIH0KICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0JlZ2luKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KQp7CiAgY29uc3QgUkdCUVVBRCAqcmdiSW47CiAgY29uc3QgUkdCUVVBRCAqcmdiT3V0OwogIFVJTlQgIGk7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLHBpLGxwYmlJbixscGJpT3V0KTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscGJpSW4gPT0gTlVMTCB8fCBscGJpT3V0ID09IE5VTEwpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CiAgaWYgKERlY29tcHJlc3NRdWVyeShwaSwgbHBiaUluLCBscGJpT3V0KSAhPSBJQ0VSUl9PSykKICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CgogIC8qIEZJWE1FOiBjYW5ub3QgY29tcHJlc3MgYW5kIGRlY29tcHJlc3MgYXQgYSB0aW1lISAqLwogIGlmIChwaS0+YkNvbXByZXNzKSB7CiAgICBGSVhNRSgiY2Fubm90IGNvbXByZXNzIGFuZCBkZWNvbXByZXNzIGF0IHNhbWUgdGltZSFcbiIpOwogICAgcmV0dXJuIElDRVJSX0VSUk9SOwogIH0KCiAgaWYgKHBpLT5iRGVjb21wcmVzcykKICAgIERlY29tcHJlc3NFbmQocGkpOwoKICByZ2JJbiAgPSAoY29uc3QgUkdCUVVBRCopKChjb25zdCBCWVRFKilscGJpSW4gICsgbHBiaUluLT5iaVNpemUpOwogIHJnYk91dCA9IChjb25zdCBSR0JRVUFEKikoKGNvbnN0IEJZVEUqKWxwYmlPdXQgKyBscGJpT3V0LT5iaVNpemUpOwoKICBzd2l0Y2ggKGxwYmlPdXQtPmJpQml0Q291bnQpIHsKICBjYXNlIDQ6CiAgY2FzZSA4OgogICAgcGktPnBhbGV0dGVfbWFwID0gKExQQllURSlMb2NhbEFsbG9jKExQVFIsIGxwYmlJbi0+YmlDbHJVc2VkKTsKICAgIGlmIChwaS0+cGFsZXR0ZV9tYXAgPT0gTlVMTCkKICAgICAgcmV0dXJuIElDRVJSX01FTU9SWTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbHBiaUluLT5iaUNsclVzZWQ7IGkrKykgewogICAgICBwaS0+cGFsZXR0ZV9tYXBbaV0gPSBNU1JMRTMyX0dldE5lYXJlc3RQYWxldHRlSW5kZXgobHBiaU91dC0+YmlDbHJVc2VkLCByZ2JPdXQsIHJnYkluW2ldKTsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgMTU6CiAgY2FzZSAxNjoKICAgIHBpLT5wYWxldHRlX21hcCA9IChMUEJZVEUpTG9jYWxBbGxvYyhMUFRSLCBscGJpSW4tPmJpQ2xyVXNlZCAqIDIpOwogICAgaWYgKHBpLT5wYWxldHRlX21hcCA9PSBOVUxMKQogICAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwoKICAgIGZvciAoaSA9IDA7IGkgPCBscGJpSW4tPmJpQ2xyVXNlZDsgaSsrKSB7CiAgICAgIFdPUkQgY29sb3I7CgogICAgICBpZiAobHBiaU91dC0+YmlCaXRDb3VudCA9PSAxNSkKCWNvbG9yID0gKChyZ2JJbltpXS5yZ2JSZWQgPj4gMykgPDwgMTApCgkgIHwgKChyZ2JJbltpXS5yZ2JHcmVlbiA+PiAzKSA8PCA1KSB8IChyZ2JJbltpXS5yZ2JCbHVlID4+IDMpOwogICAgICBlbHNlCgljb2xvciA9ICgocmdiSW5baV0ucmdiUmVkID4+IDMpIDw8IDExKQoJICB8ICgocmdiSW5baV0ucmdiR3JlZW4gPj4gMykgPDwgNSkgfCAocmdiSW5baV0ucmdiQmx1ZSA+PiAzKTsKCiAgICAgIHBpLT5wYWxldHRlX21hcFtpICogMiArIDFdID0gY29sb3IgPj4gODsKICAgICAgcGktPnBhbGV0dGVfbWFwW2kgKiAyICsgMF0gPSBjb2xvciAmIDB4RkY7CiAgICB9OwogICAgYnJlYWs7CiAgY2FzZSAyNDoKICBjYXNlIDMyOgogICAgcGktPnBhbGV0dGVfbWFwID0gKExQQllURSlMb2NhbEFsbG9jKExQVFIsIGxwYmlJbi0+YmlDbHJVc2VkICogc2l6ZW9mKFJHQlFVQUQpKTsKICAgIGlmIChwaS0+cGFsZXR0ZV9tYXAgPT0gTlVMTCkKICAgICAgcmV0dXJuIElDRVJSX01FTU9SWTsKICAgIG1lbWNweShwaS0+cGFsZXR0ZV9tYXAsIHJnYkluLCBscGJpSW4tPmJpQ2xyVXNlZCAqIHNpemVvZihSR0JRVUFEKSk7CiAgICBicmVhazsKICB9OwoKICBwaS0+YkRlY29tcHJlc3MgPSBUUlVFOwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3MoQ29kZWNJbmZvICpwaSwgSUNERUNPTVBSRVNTICpwaWMsIERXT1JEIGR3U2l6ZSkKewogIFRSQUNFKCIoJXAsJXAsJXUpXG4iLHBpLHBpYyxkd1NpemUpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHBpYyA9PSBOVUxMKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwogIGlmIChwaWMtPmxwYmlJbnB1dCA9PSBOVUxMIHx8IHBpYy0+bHBJbnB1dCA9PSBOVUxMIHx8CiAgICAgIHBpYy0+bHBiaU91dHB1dCA9PSBOVUxMIHx8IHBpYy0+bHBPdXRwdXQgPT0gTlVMTCkKICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKCiAgLyogY2hlY2sgZm9ybWF0cyAqLwogIGlmICghIHBpLT5iRGVjb21wcmVzcykgewogICAgTFJFU1VMVCBociA9IERlY29tcHJlc3NCZWdpbihwaSwgcGljLT5scGJpSW5wdXQsIHBpYy0+bHBiaU91dHB1dCk7CiAgICBpZiAoaHIgIT0gSUNFUlJfT0spCiAgICAgIHJldHVybiBocjsKICB9IGVsc2UgaWYgKERlY29tcHJlc3NRdWVyeShwaSwgcGljLT5scGJpSW5wdXQsIHBpYy0+bHBiaU91dHB1dCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwoKICBhc3NlcnQocGljLT5scGJpSW5wdXQtPmJpV2lkdGggID09IHBpYy0+bHBiaU91dHB1dC0+YmlXaWR0aCk7CiAgYXNzZXJ0KHBpYy0+bHBiaUlucHV0LT5iaUhlaWdodCA9PSBwaWMtPmxwYmlPdXRwdXQtPmJpSGVpZ2h0KTsKCiAgcGljLT5scGJpT3V0cHV0LT5iaVNpemVJbWFnZSA9IERJQldJRFRIQllURVMoKnBpYy0+bHBiaU91dHB1dCkgKiBwaWMtPmxwYmlPdXRwdXQtPmJpSGVpZ2h0OwogIGlmIChwaWMtPmxwYmlJbnB1dC0+YmlCaXRDb3VudCA9PSA0KQogICAgcmV0dXJuIE1TUkxFMzJfRGVjb21wcmVzc1JMRTQocGksIHBpYy0+bHBiaU91dHB1dCwgcGljLT5scElucHV0LCBwaWMtPmxwT3V0cHV0KTsKICBlbHNlCiAgICByZXR1cm4gTVNSTEUzMl9EZWNvbXByZXNzUkxFOChwaSwgcGljLT5scGJpT3V0cHV0LCBwaWMtPmxwSW5wdXQsIHBpYy0+bHBPdXRwdXQpOwp9CgpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzRW5kKENvZGVjSW5mbyAqcGkpCnsKICBUUkFDRSgiKCVwKVxuIixwaSk7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIHBpLT5iRGVjb21wcmVzcyA9IEZBTFNFOwoKICBpZiAocGktPnBhbGV0dGVfbWFwICE9IE5VTEwpIHsKICAgIExvY2FsRnJlZSgoSExPQ0FMKXBpLT5wYWxldHRlX21hcCk7CiAgICBwaS0+cGFsZXR0ZV9tYXAgPSBOVUxMOwogIH0KCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzR2V0UGFsZXR0ZShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJCSAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIGludCBzaXplOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIixwaSxscGJpSW4sbHBiaU91dCk7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHBiaUluID09IE5VTEwgfHwgbHBiaU91dCA9PSBOVUxMKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwoKICBpZiAoRGVjb21wcmVzc1F1ZXJ5KHBpLCBscGJpSW4sIGxwYmlPdXQpICE9IElDRVJSX09LKQogICAgcmV0dXJuIElDRVJSX0JBREZPUk1BVDsKCiAgaWYgKGxwYmlPdXQtPmJpQml0Q291bnQgPiA4KQogICAgcmV0dXJuIElDRVJSX0VSUk9SOwoKICBpZiAobHBiaUluLT5iaUJpdENvdW50IDw9IDgpIHsKICAgIGlmIChscGJpSW4tPmJpQ2xyVXNlZCA+IDApCiAgICAgIHNpemUgPSBscGJpSW4tPmJpQ2xyVXNlZDsKICAgIGVsc2UKICAgICAgc2l6ZSA9ICgxIDw8IGxwYmlJbi0+YmlCaXRDb3VudCk7CgogICAgbHBiaU91dC0+YmlDbHJVc2VkID0gc2l6ZTsKCiAgICBtZW1jcHkoKExQQllURSlscGJpT3V0ICsgbHBiaU91dC0+YmlTaXplLCAoY29uc3QgQllURSopbHBiaUluICsgbHBiaUluLT5iaVNpemUsIHNpemUgKiBzaXplb2YoUkdCUVVBRCkpOwogIH0gLyogZWxzZSBjb3VsZCBuZXZlciBvY2N1ciAhICovCgogIHJldHVybiBJQ0VSUl9PSzsKfQoKLyogRHJpdmVyUHJvYyAtIGVudHJ5IHBvaW50IGZvciBhbiBpbnN0YWxsYWJsZSBkcml2ZXIgKi8KTFJFU1VMVCBDQUxMQkFDSyBNU1JMRTMyX0RyaXZlclByb2MoRFdPUkRfUFRSIGR3RHJ2SUQsIEhEUlZSIGhEcnYsIFVJTlQgdU1zZywKCQkJCSAgICBMUEFSQU0gbFBhcmFtMSwgTFBBUkFNIGxQYXJhbTIpCnsKICBDb2RlY0luZm8gKnBpID0gKENvZGVjSW5mbyopZHdEcnZJRDsKCiAgVFJBQ0UoIiglbHgsJXAsMHglMDRYLDB4JTA4bFgsMHglMDhsWClcbiIsIGR3RHJ2SUQsIGhEcnYsIHVNc2csIGxQYXJhbTEsIGxQYXJhbTIpOwoKICBzd2l0Y2ggKHVNc2cpIHsKICAgIC8qIHN0YW5kYXJkIGRyaXZlciBtZXNzYWdlcyAqLwogIGNhc2UgRFJWX0xPQUQ6CiAgICByZXR1cm4gRFJWQ05GX09LOwogIGNhc2UgRFJWX09QRU46CiAgICAgIHJldHVybiAoTFJFU1VMVClPcGVuKChJQ09QRU4qKWxQYXJhbTIpOwogIGNhc2UgRFJWX0NMT1NFOgogICAgaWYgKGR3RHJ2SUQgIT0gMHhGRkZGMDAwMCAmJiAoTFBWT0lEKWR3RHJ2SUQgIT0gTlVMTCkKICAgICAgQ2xvc2UocGkpOwogICAgcmV0dXJuIERSVkNORl9PSzsKICBjYXNlIERSVl9FTkFCTEU6CiAgY2FzZSBEUlZfRElTQUJMRToKICAgIHJldHVybiBEUlZDTkZfT0s7CiAgY2FzZSBEUlZfRlJFRToKICAgIHJldHVybiBEUlZDTkZfT0s7CiAgY2FzZSBEUlZfUVVFUllDT05GSUdVUkU6CiAgICByZXR1cm4gRFJWQ05GX0NBTkNFTDsgLyogRklYTUUgKi8KICBjYXNlIERSVl9DT05GSUdVUkU6CiAgICByZXR1cm4gRFJWQ05GX09LOyAgICAgLyogRklYTUUgKi8KICBjYXNlIERSVl9JTlNUQUxMOgogIGNhc2UgRFJWX1JFTU9WRToKICAgIHJldHVybiBEUlZDTkZfT0s7CgogICAgLyogaW5zdGFsbGFibGUgY29tcHJlc3Npb24gbWFuYWdlciBtZXNzYWdlcyAqLwogIGNhc2UgSUNNX0NPTkZJR1VSRToKICAgIEZJWE1FKCJJQ01fQ09ORklHVVJFICglbGQpXG4iLGxQYXJhbTEpOwogICAgaWYgKGxQYXJhbTEgPT0gLTEpCiAgICAgIHJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsgLyogRklYTUUgKi8KICAgIGVsc2UKICAgICAgcmV0dXJuIENvbmZpZ3VyZShwaSwgKEhXTkQpbFBhcmFtMSk7CiAgY2FzZSBJQ01fQUJPVVQ6CiAgICBpZiAobFBhcmFtMSA9PSAtMSkKICAgICAgcmV0dXJuIElDRVJSX09LOwogICAgZWxzZQogICAgICByZXR1cm4gQWJvdXQocGksIChIV05EKWxQYXJhbTEpOwogIGNhc2UgSUNNX0dFVFNUQVRFOgogIGNhc2UgSUNNX1NFVFNUQVRFOgogICAgcmV0dXJuIDA7IC8qIG5vIHN0YXRlICovCiAgY2FzZSBJQ01fR0VUSU5GTzoKICAgIHJldHVybiBHZXRJbmZvKHBpLCAoSUNJTkZPKilsUGFyYW0xLCAoRFdPUkQpbFBhcmFtMik7CiAgY2FzZSBJQ01fR0VUREVGQVVMVFFVQUxJVFk6CiAgICBpZiAoKExQVk9JRClsUGFyYW0xICE9IE5VTEwpIHsKICAgICAgKigoTFBEV09SRClsUGFyYW0xKSA9IE1TUkxFMzJfREVGQVVMVFFVQUxJVFk7CiAgICAgIHJldHVybiBJQ0VSUl9PSzsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgSUNNX0dFVFFVQUxJVFk6CiAgICBpZiAoKExQVk9JRClsUGFyYW0xICE9IE5VTEwpIHsKICAgICAgKigoTFBEV09SRClsUGFyYW0xKSA9IHBpLT5kd1F1YWxpdHk7CiAgICAgIHJldHVybiBJQ0VSUl9PSzsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgSUNNX1NFVFFVQUxJVFk6CiAgICByZXR1cm4gU2V0UXVhbGl0eShwaSwgKihMUExPTkcpbFBhcmFtMSk7CiAgY2FzZSBJQ01fQ09NUFJFU1NfR0VUX0ZPUk1BVDoKICAgIHJldHVybiBDb21wcmVzc0dldEZvcm1hdChwaSwgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJICAgICAoTFBCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTIpOwogIGNhc2UgSUNNX0NPTVBSRVNTX0dFVF9TSVpFOgogICAgcmV0dXJuIENvbXByZXNzR2V0U2l6ZShwaSwgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJICAgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMik7CiAgY2FzZSBJQ01fQ09NUFJFU1NfUVVFUlk6CiAgICByZXR1cm4gQ29tcHJlc3NRdWVyeShwaSwgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTIpOwogIGNhc2UgSUNNX0NPTVBSRVNTX0JFR0lOOgogICAgcmV0dXJuIENvbXByZXNzQmVnaW4ocGksIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTEsCgkJCSAoTFBDQklUTUFQSU5GT0hFQURFUilsUGFyYW0yKTsKICBjYXNlIElDTV9DT01QUkVTUzoKICAgIHJldHVybiBDb21wcmVzcyhwaSwgKElDQ09NUFJFU1MqKWxQYXJhbTEsIChEV09SRClsUGFyYW0yKTsKICBjYXNlIElDTV9DT01QUkVTU19FTkQ6CiAgICByZXR1cm4gQ29tcHJlc3NFbmQocGkpOwogIGNhc2UgSUNNX0RFQ09NUFJFU1NfR0VUX0ZPUk1BVDoKICAgIHJldHVybiBEZWNvbXByZXNzR2V0Rm9ybWF0KHBpLCAoTFBDQklUTUFQSU5GT0hFQURFUilsUGFyYW0xLAoJCQkgICAgICAgKExQQklUTUFQSU5GT0hFQURFUilsUGFyYW0yKTsKICBjYXNlIElDTV9ERUNPTVBSRVNTX1FVRVJZOgogICAgcmV0dXJuIERlY29tcHJlc3NRdWVyeShwaSwgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJICAgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMik7CiAgY2FzZSBJQ01fREVDT01QUkVTU19CRUdJTjoKICAgIHJldHVybiBEZWNvbXByZXNzQmVnaW4ocGksIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTEsCgkJCSAgIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTIpOwogIGNhc2UgSUNNX0RFQ09NUFJFU1M6CiAgICByZXR1cm4gRGVjb21wcmVzcyhwaSwgKElDREVDT01QUkVTUyopbFBhcmFtMSwgKERXT1JEKWxQYXJhbTIpOwogIGNhc2UgSUNNX0RFQ09NUFJFU1NfRU5EOgogICAgcmV0dXJuIERlY29tcHJlc3NFbmQocGkpOwogIGNhc2UgSUNNX0RFQ09NUFJFU1NfU0VUX1BBTEVUVEU6CiAgICBGSVhNRSgiKC4uLikgLT4gU2V0UGFsZXR0ZSglcCwlcCwlcCk6IHN0dWIhXG4iLCBwaSwgKExQVk9JRClsUGFyYW0xLCAoTFBWT0lEKWxQYXJhbTIpOwogICAgcmV0dXJuIElDRVJSX1VOU1VQUE9SVEVEOwogIGNhc2UgSUNNX0RFQ09NUFJFU1NfR0VUX1BBTEVUVEU6CiAgICByZXR1cm4gRGVjb21wcmVzc0dldFBhbGV0dGUocGksIChMUEJJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJCShMUEJJVE1BUElORk9IRUFERVIpbFBhcmFtMik7CiAgY2FzZSBJQ01fR0VUREVGQVVMVEtFWUZSQU1FUkFURToKICAgIGlmICgoTFBWT0lEKWxQYXJhbTEgIT0gTlVMTCkKICAgICAgKihMUERXT1JEKWxQYXJhbTEgPSAxNTsKICAgIHJldHVybiBJQ0VSUl9PSzsKICBkZWZhdWx0OgogICAgaWYgKHVNc2cgPCBEUlZfVVNFUikKICAgICAgcmV0dXJuIERlZkRyaXZlclByb2MoZHdEcnZJRCwgaERydiwgdU1zZywgbFBhcmFtMSwgbFBhcmFtMik7CiAgICBlbHNlCiAgICAgIEZJWE1FKCJVbmtub3duIG1lc3NhZ2UgdU1zZz0weCUwOFggbFBhcmFtMT0weCUwOGxYIGxQYXJhbTI9MHglMDhsWFxuIix1TXNnLGxQYXJhbTEsbFBhcmFtMik7CiAgfTsKCiAgcmV0dXJuIElDRVJSX1VOU1VQUE9SVEVEOwp9CgovKiBEbGxNYWluIC0gbGlicmFyeSBpbml0aWFsaXphdGlvbiBjb2RlICovCkJPT0wgV0lOQVBJIERsbE1haW4oSElOU1RBTkNFIGhNb2R1bGUsIERXT1JEIGR3UmVhc29uLCBMUFZPSUQgbHBSZXNlcnZlZCkKewogIFRSQUNFKCIoJXAsJWQsJXApXG4iLChMUFZPSUQpaE1vZHVsZSxkd1JlYXNvbixscFJlc2VydmVkKTsKCiAgc3dpdGNoIChkd1JlYXNvbikgewogIGNhc2UgRExMX1BST0NFU1NfQVRUQUNIOgogICAgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhoTW9kdWxlKTsKICAgIE1TUkxFMzJfaE1vZHVsZSA9IGhNb2R1bGU7CiAgICBicmVhazsKCiAgY2FzZSBETExfUFJPQ0VTU19ERVRBQ0g6CiAgICBicmVhazsKICB9CgogIHJldHVybiBUUlVFOwp9Cg==