LyoKICogQ29weXJpZ2h0IDIwMDItMjAwMyBNaWNoYWVsIEf8bm5ld2lnCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCi8qIFRPRE86CiAqICAgLSBzb21lIGltcHJvdmVtZW50cyBwb3NzaWJsZQogKiAgIC0gaW1wbGVtZW50IERlY29tcHJlc3NTZXRQYWxldHRlPyAtLSBkb2VzIHdlIG5lZWQgaXQgZm9yIGFueXRoaW5nPwogKi8KCiNpbmNsdWRlIDxhc3NlcnQuaD4KCiNpbmNsdWRlICJtc3JsZV9wcml2YXRlLmgiCgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5kb3dzeC5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1zcmxlMzIpOwoKc3RhdGljIEhJTlNUQU5DRSBNU1JMRTMyX2hNb2R1bGUgPSAwOwoKI2RlZmluZSBBQlMoYSkgICAgICAgICAgICAgICAgKChhKSA8IDAgPyAtKGEpIDogKGEpKQojZGVmaW5lIFNRUihhKSAgICAgICAgICAgICAgICAoKGEpICogKGEpKQoKI2RlZmluZSBRVUFMSVRZX3RvX0RJU1QocSkgICAgKElDUVVBTElUWV9ISUdIIC0gcSkKaW5saW5lIFdPUkQgQ29sb3JDbXAoV09SRCBjbHIxLCBXT1JEIGNscjIpCnsKICByZWdpc3RlciBVSU5UIGEgPSAoY2xyMS1jbHIyKTsKICByZXR1cm4gU1FSKGEpOwp9CmlubGluZSBXT1JEIEludGVuc2l0eShSR0JRVUFEIGNscikKewogIHJldHVybiAoMzAgKiBjbHIucmdiUmVkICsgNTkgKiBjbHIucmdiR3JlZW4gKyAxMSAqIGNsci5yZ2JCbHVlKS80Owp9CgojZGVmaW5lIEdldFJhd1BpeGVsKGxwYmksbHAseCkgXAogICgobHBiaSktPmJpQml0Q291bnQgPT0gMSA/ICgobHApWyh4KS84XSA+PiAoOCAtICh4KSU4KSkgJiAxIDogXAogICAoKGxwYmkpLT5iaUJpdENvdW50ID09IDQgPyAoKGxwKVsoeCkvMl0gPj4gKDQgKiAoMSAtICh4KSUyKSkpICYgMTUgOiBscFt4XSkpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiB1dGlsaXR5IGZ1bmN0aW9ucyAqLwpzdGF0aWMgQk9PTCAgICBpc1N1cHBvcnRlZERJQihMUENCSVRNQVBJTkZPSEVBREVSIGxwYmkpOwpzdGF0aWMgQk9PTCAgICBpc1N1cHBvcnRlZE1STEUoTFBDQklUTUFQSU5GT0hFQURFUiBscGJpKTsKc3RhdGljIHZvaWQgICAgTG9hZFdpZGVTdHJpbmcoVUlOVCBpZCwgTFBXU1RSIHN0ciwgSU5UIGxlbik7CnN0YXRpYyBCWVRFICAgIE1TUkxFMzJfR2V0TmVhcmVzdFBhbGV0dGVJbmRleChVSU5UIGNvdW50LCBjb25zdCBSR0JRVUFEICpjbHJzLCBSR0JRVUFEIGNscik7CgovKiBjb21wcmVzc2lvbiBmdW5jdGlvbnMgKi8Kc3RhdGljIHZvaWQgICAgY29tcHV0ZUludGVybmFsRnJhbWUoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sIExQQllURSBscEluKTsKc3RhdGljIExPTkcgICAgTVNSTEUzMl9HZXRNYXhDb21wcmVzc2VkU2l6ZShMUENCSVRNQVBJTkZPSEVBREVSIGxwYmkpOwpzdGF0aWMgTFJFU1VMVCBNU1JMRTMyX0NvbXByZXNzUkxFNChDb2RlY0luZm8gKnBpLCBMUEJJVE1BUElORk9IRUFERVIgbHBiaUluLCBMUEJZVEUgbHBJbiwgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQsIExQQllURSBscE91dCwgQk9PTCBpc0tleSk7CnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfQ29tcHJlc3NSTEU4KENvZGVjSW5mbyAqcGksIExQQklUTUFQSU5GT0hFQURFUiBscGJpSW4sIExQQllURSBscEluLCBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCwgTFBCWVRFIGxwT3V0LCBCT09MIGlzS2V5KTsKCi8qIGRlY29tcHJlc3Npb24gZnVuY3Rpb25zICovCnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfRGVjb21wcmVzc1JMRTQoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpLAoJCQkJICAgICAgTFBCWVRFIGxwSW4sIExQQllURSBscE91dCk7CnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfRGVjb21wcmVzc1JMRTgoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpLAoJCQkJICAgICAgTFBCWVRFIGxwSW4sIExQQllURSBscE91dCk7CgovKiBBUEkgZnVuY3Rpb25zICovCnN0YXRpYyBMUkVTVUxUIENvbXByZXNzR2V0Rm9ybWF0KENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkJIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KTsKc3RhdGljIExSRVNVTFQgQ29tcHJlc3NHZXRTaXplKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KTsKc3RhdGljIExSRVNVTFQgQ29tcHJlc3NRdWVyeShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJICAgICBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpOwpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0JlZ2luKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCk7CnN0YXRpYyBMUkVTVUxUIENvbXByZXNzKENvZGVjSW5mbyAqcGksIElDQ09NUFJFU1MqIGxwaWMsIERXT1JEIGR3U2l6ZSk7CnN0YXRpYyBMUkVTVUxUIENvbXByZXNzRW5kKENvZGVjSW5mbyAqcGkpOwoKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0dldEZvcm1hdChDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJCSAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KTsKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc1F1ZXJ5KENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KTsKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0JlZ2luKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KTsKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzcyhDb2RlY0luZm8gKnBpLCBJQ0RFQ09NUFJFU1MgKnBpYywgRFdPUkQgZHdTaXplKTsKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0VuZChDb2RlY0luZm8gKnBpKTsKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc0dldFBhbGV0dGUoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCQkgICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQgTG9hZFdpZGVTdHJpbmcoVUlOVCBpZCwgTFBXU1RSIHN0ciwgSU5UIGxlbikKewogIGNoYXIgc3pUZW1wWzgwXTsKCiAgTG9hZFN0cmluZ0EoTVNSTEUzMl9oTW9kdWxlLCBpZCwgc3pUZW1wLCBzaXplb2Yoc3pUZW1wKSk7CiAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN6VGVtcCwgLTEsIHN0ciwgbGVuKTsKfQoKc3RhdGljIEJPT0wgaXNTdXBwb3J0ZWRNUkxFKExQQ0JJVE1BUElORk9IRUFERVIgbHBiaSkKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KGxwYmkgIT0gTlVMTCk7CgogIGlmIChscGJpLT5iaVNpemUgPCBzaXplb2YoQklUTUFQSU5GT0hFQURFUikgfHwgXAogICAgICBscGJpLT5iaVBsYW5lcyAhPSAxKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiA9PSBCSV9STEU0KSB7CiAgICBpZiAobHBiaS0+YmlCaXRDb3VudCAhPSA0IHx8IFwKCShscGJpLT5iaVdpZHRoICUgMikgIT0gMCkKICAgICAgcmV0dXJuIEZBTFNFOwogIH0gZWxzZSBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiA9PSBCSV9STEU4KSB7CiAgICBpZiAobHBiaS0+YmlCaXRDb3VudCAhPSA4KQogICAgICByZXR1cm4gRkFMU0U7CiAgfSBlbHNlCiAgICByZXR1cm4gRkFMU0U7CgogIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCAgaXNTdXBwb3J0ZWRESUIoTFBDQklUTUFQSU5GT0hFQURFUiBscGJpKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQobHBiaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgc3RydWN0dXJlIHZlcnNpb24vcGxhbmVzL2NvbXByZXNzaW9uICovCiAgaWYgKGxwYmktPmJpU2l6ZSA8IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSB8fAogICAgICBscGJpLT5iaVBsYW5lcyAhPSAxKQogICAgcmV0dXJuIEZBTFNFOwogIGlmIChscGJpLT5iaUNvbXByZXNzaW9uICE9IEJJX1JHQiAmJgogICAgICBscGJpLT5iaUNvbXByZXNzaW9uICE9IEJJX0JJVEZJRUxEUykKICAgIHJldHVybiBGQUxTRTsKCiAgLyogY2hlY2sgYml0LWRlcHRoICovCiAgaWYgKGxwYmktPmJpQml0Q291bnQgIT0gMSAmJgogICAgICBscGJpLT5iaUJpdENvdW50ICE9IDQgJiYKICAgICAgbHBiaS0+YmlCaXRDb3VudCAhPSA4ICYmCiAgICAgIGxwYmktPmJpQml0Q291bnQgIT0gMTUgJiYKICAgICAgbHBiaS0+YmlCaXRDb3VudCAhPSAxNiAmJgogICAgICBscGJpLT5iaUJpdENvdW50ICE9IDI0ICYmCiAgICAgIGxwYmktPmJpQml0Q291bnQgIT0gMzIpCiAgICByZXR1cm4gRkFMU0U7CgogIC8qIGNoZWNrIGZvciBzaXplKHMpICovCiAgaWYgKCFscGJpLT5iaVdpZHRoIHx8ICFscGJpLT5iaUhlaWdodCkKICAgIHJldHVybiBGQUxTRTsgLyogaW1hZ2Ugd2l0aCB6ZXJvIHNpemUsIG1ha2VzIG5vIHNlbnNlIHNvIGVycm9yICEgKi8KICBpZiAoRElCV0lEVEhCWVRFUygqbHBiaSkgKiAoRFdPUkQpbHBiaS0+YmlIZWlnaHQgPj0gKDFVTCA8PCAzMSkgLSAxKQogICAgcmV0dXJuIEZBTFNFOyAvKiBpbWFnZSB0b28gYmlnICEgKi8KCiAgLyogY2hlY2sgZm9yIG5vbi1leGlzdGVudCBjb2xvcnRhYmxlIGZvciBoaS0gYW5kIHRydWUtY29sb3IgRElCJ3MgKi8KICBpZiAobHBiaS0+YmlCaXRDb3VudCA+PSAxNSAmJiBscGJpLT5iaUNsclVzZWQgPiAwKQogICAgcmV0dXJuIEZBTFNFOwoKICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJZVEUgTVNSTEUzMl9HZXROZWFyZXN0UGFsZXR0ZUluZGV4KFVJTlQgY291bnQsIGNvbnN0IFJHQlFVQUQgKmNscnMsIFJHQlFVQUQgY2xyKQp7CiAgSU5UICBkaWZmID0gMHgwMEZGRkZGRjsKICBVSU5UIGk7CiAgVUlOVCBpZHggPSAwOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChjbHJzICE9IE5VTEwpOwoKICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewogICAgaW50IHIgPSAoKGludCljbHJzW2ldLnJnYlJlZCAgIC0gKGludCljbHIucmdiUmVkKTsKICAgIGludCBnID0gKChpbnQpY2xyc1tpXS5yZ2JHcmVlbiAtIChpbnQpY2xyLnJnYkdyZWVuKTsKICAgIGludCBiID0gKChpbnQpY2xyc1tpXS5yZ2JCbHVlICAtIChpbnQpY2xyLnJnYkJsdWUpOwoKICAgIHIgPSByKnIgKyBnKmcgKyBiKmI7CgogICAgaWYgKHIgPCBkaWZmKSB7CiAgICAgIGlkeCAgPSBpOwogICAgICBkaWZmID0gcjsKICAgICAgaWYgKGRpZmYgPT0gMCkKCWJyZWFrOwogICAgfQogIH0KCiAgcmV0dXJuIGlkeDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZCBjb21wdXRlSW50ZXJuYWxGcmFtZShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwgTFBCWVRFIGxwSW4pCnsKICBXT1JEICAgd0ludGVuc2l0eVRibFsyNTZdOwogIERXT1JEICBsSW5MaW5lLCBsT3V0TGluZTsKICBMUFdPUkQgbHBPdXQ7CiAgVUlOVCAgIGk7CiAgTE9ORyAgIHk7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KHBpICE9IE5VTEwgJiYgbHBiaUluICE9IE5VTEwgJiYgbHBJbiAhPSBOVUxMKTsKICBhc3NlcnQocGktPnBDdXJGcmFtZSAhPSBOVUxMKTsKCiAgbEluTGluZSAgPSBESUJXSURUSEJZVEVTKCpscGJpSW4pOwogIGxPdXRMaW5lID0gV0lEVEhCWVRFUygoV09SRClscGJpSW4tPmJpV2lkdGggKiA4dSAqIHNpemVvZihXT1JEKSkgLyAydTsKICBscE91dCAgICA9IHBpLT5wQ3VyRnJhbWU7CgogIGFzc2VydChscGJpSW4tPmJpQ2xyVXNlZCAhPSAwKTsKCiAgewogICAgY29uc3QgUkdCUVVBRCAqbHAgPQogICAgICAoY29uc3QgUkdCUVVBRCAqKSgoY29uc3QgQllURSopbHBiaUluICsgbHBiaUluLT5iaVNpemUpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBscGJpSW4tPmJpQ2xyVXNlZDsgaSsrKQogICAgICB3SW50ZW5zaXR5VGJsW2ldID0gSW50ZW5zaXR5KGxwW2ldKTsKICB9CgogIGZvciAoeSA9IDA7IHkgPCBscGJpSW4tPmJpSGVpZ2h0OyB5KyspIHsKICAgIExPTkcgeDsKCiAgICBzd2l0Y2ggKGxwYmlJbi0+YmlCaXRDb3VudCkgewogICAgY2FzZSAxOgogICAgICBmb3IgKHggPSAwOyB4IDwgbHBiaUluLT5iaVdpZHRoIC8gODsgeCsrKSB7Cglmb3IgKGkgPSAwOyBpIDwgNzsgaSsrKQoJICBscE91dFs4ICogeCArIGldID0gd0ludGVuc2l0eVRibFsobHBJblt4XSA+PiAoNyAtIGkpKSAmIDFdOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSA0OgogICAgICBmb3IgKHggPSAwOyB4IDwgbHBiaUluLT5iaVdpZHRoIC8gMjsgeCsrKSB7CglscE91dFsyICogeCArIDBdID0gd0ludGVuc2l0eVRibFsobHBJblt4XSA+PiA0KV07CglscE91dFsyICogeCArIDFdID0gd0ludGVuc2l0eVRibFsobHBJblt4XSAmIDB4MEYpXTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgODoKICAgICAgZm9yICh4ID0gMDsgeCA8IGxwYmlJbi0+YmlXaWR0aDsgeCsrKQoJbHBPdXRbeF0gPSB3SW50ZW5zaXR5VGJsW2xwSW5beF1dOwogICAgICBicmVhazsKICAgIH0KCiAgICBscEluICArPSBsSW5MaW5lOwogICAgbHBPdXQgKz0gbE91dExpbmU7CiAgfQp9CgpzdGF0aWMgTE9ORyBNU1JMRTMyX0dldE1heENvbXByZXNzZWRTaXplKExQQ0JJVE1BUElORk9IRUFERVIgbHBiaSkKewogIExPTkcgYSwgYiwgc2l6ZTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChscGJpICE9IE5VTEwpOwoKICBhID0gbHBiaS0+YmlXaWR0aCAvIDI1NTsKICBiID0gbHBiaS0+YmlXaWR0aCAlIDI1NTsKICBpZiAobHBiaS0+YmlCaXRDb3VudCA8PSA0KSB7CiAgICBhIC89IDI7CiAgICBiIC89IDI7CiAgfQoKICBzaXplID0gKDIgKyBhICogKDIgKyAoKGEgKyAyKSAmIH4yKSkgKyBiICogKDIgKyAoKGIgKyAyKSAmIH4yKSkpOwogIHJldHVybiBzaXplICogbHBiaS0+YmlIZWlnaHQ7Cn0KCi8qIGxwUCA9PiBjdXJyZW50ICBwb3MgaW4gcHJldmlvdXMgZnJhbWUKICogbHBBID0+IHByZXZpb3VzIHBvcyBpbiBjdXJyZW50ICBmcmFtZQogKiBscEIgPT4gY3VycmVudCAgcG9zIGluIGN1cnJlbnQgIGZyYW1lCiAqLwpzdGF0aWMgSU5UIGNvdW50RGlmZlJMRTQoTFBXT1JEIGxwUCwgTFBXT1JEIGxwQSwgTFBXT1JEIGxwQiwgSU5UIHBvcywgTE9ORyBsRGlzdCwgTE9ORyB3aWR0aCkKewogIElOVCAgY291bnQ7CiAgV09SRCBjbHIxLCBjbHIyOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChscEEgJiYgbHBCICYmIGxEaXN0ID49IDAgJiYgd2lkdGggPiAwKTsKCiAgaWYgKHBvcyA+PSB3aWR0aCkKICAgIHJldHVybiAwOwogIGlmIChwb3MrMSA9PSB3aWR0aCkKICAgIHJldHVybiAxOwoKICBjbHIxID0gbHBCW3BvcysrXTsKICBjbHIyID0gbHBCW3Bvc107CgogIGNvdW50ID0gMjsKICB3aGlsZSAocG9zICsgMSA8IHdpZHRoKSB7CiAgICBXT1JEIGNscjMsIGNscjQ7CgogICAgY2xyMyA9IGxwQlsrK3Bvc107CiAgICBpZiAocG9zICsgMSA+PSB3aWR0aCkKICAgICAgcmV0dXJuIGNvdW50ICsgMTsKCiAgICBjbHI0ID0gbHBCWysrcG9zXTsKICAgIGlmIChDb2xvckNtcChjbHIxLCBjbHIzKSA8PSBsRGlzdCAmJgoJQ29sb3JDbXAoY2xyMiwgY2xyNCkgPD0gbERpc3QpIHsKICAgICAgLyogZGlmZiBhdCBlbmQ/IC0tIGxvb2stYWhlYWQgZm9yIGF0bGVhc3QgPz8gbW9yZSBlbmNvZGFibGUgcGl4ZWwgKi8KICAgICAgaWYgKHBvcyArIDIgPCB3aWR0aCAmJiBDb2xvckNtcChjbHIxLGxwQltwb3MrMV0pIDw9IGxEaXN0ICYmCgkgIENvbG9yQ21wKGNscjIsbHBCW3BvcysyXSkgPD0gbERpc3QpIHsKCWlmIChwb3MgKyA0IDwgd2lkdGggJiYgQ29sb3JDbXAobHBCW3BvcysxXSxscEJbcG9zKzNdKSA8PSBsRGlzdCAmJgoJICAgIENvbG9yQ21wKGxwQltwb3MrMl0sbHBCW3Bvcys0XSkgPD0gbERpc3QpCgkgIHJldHVybiBjb3VudCAtIDM7IC8qIGZvbGxvd2VkIGJ5IGF0bGVhc3QgNCBlbmNvZGFibGUgcGl4ZWxzICovCglyZXR1cm4gY291bnQgLSAyOwogICAgICB9CiAgICB9IGVsc2UgaWYgKGxwUCAhPSBOVUxMICYmIENvbG9yQ21wKGxwUFtwb3NdLCBscEJbcG9zXSkgPD0gbERpc3QpIHsKICAgICAgLyogJ2NvbXBhcmUnIHdpdGggcHJldmlvdXMgZnJhbWUgZm9yIGVuZCBvZiBkaWZmICovCiAgICAgIElOVCBjb3VudDIgPSAwOwoKICAgICAgLyogRklYTUUgKi8KCiAgICAgIGlmIChjb3VudDIgPj0gOCkKCXJldHVybiBjb3VudDsKCiAgICAgIHBvcyAtPSBjb3VudDI7CiAgICB9CgogICAgY291bnQgKz0gMjsKICAgIGNscjEgPSBjbHIzOwogICAgY2xyMiA9IGNscjQ7CiAgfQoKICByZXR1cm4gY291bnQ7Cn0KCi8qIGxwUCA9PiBjdXJyZW50ICBwb3MgaW4gcHJldmlvdXMgZnJhbWUKICogbHBBID0+IHByZXZpb3VzIHBvcyBpbiBjdXJyZW50ICBmcmFtZQogKiBscEIgPT4gY3VycmVudCAgcG9zIGluIGN1cnJlbnQgIGZyYW1lCiAqLwpzdGF0aWMgSU5UIGNvdW50RGlmZlJMRTgoTFBXT1JEIGxwUCwgTFBXT1JEIGxwQSwgTFBXT1JEIGxwQiwgSU5UIHBvcywgTE9ORyBsRGlzdCwgTE9ORyB3aWR0aCkKewogIElOVCBjb3VudDsKCiAgZm9yIChjb3VudCA9IDA7IHBvcyA8IHdpZHRoOyBwb3MrKywgY291bnQrKykgewogICAgaWYgKENvbG9yQ21wKGxwQVtwb3NdLCBscEJbcG9zXSkgPD0gbERpc3QpIHsKICAgICAgLyogZGlmZiBhdCBlbmQ/IC0tIGxvb2stYWhlYWQgZm9yIHNvbWUgbW9yZSBlbmNvZGFibGUgcGl4ZWwgKi8KICAgICAgaWYgKHBvcyArIDEgPCB3aWR0aCAmJiBDb2xvckNtcChscEJbcG9zXSwgbHBCW3BvcysxXSkgPD0gbERpc3QpCglyZXR1cm4gY291bnQgLSAxOwogICAgICBpZiAocG9zICsgMiA8IHdpZHRoICYmIENvbG9yQ21wKGxwQltwb3MrMV0sIGxwQltwb3MrMl0pIDw9IGxEaXN0KQoJcmV0dXJuIGNvdW50IC0gMTsKICAgIH0gZWxzZSBpZiAobHBQICE9IE5VTEwgJiYgQ29sb3JDbXAobHBQW3Bvc10sIGxwQltwb3NdKSA8PSBsRGlzdCkgewogICAgICAvKiAnY29tcGFyZScgd2l0aCBwcmV2aW91cyBmcmFtZSBmb3IgZW5kIG9mIGRpZmYgKi8KICAgICAgSU5UIGNvdW50MiA9IDA7CgogICAgICBmb3IgKGNvdW50MiA9IDAsIHBvcysrOyBwb3MgPCB3aWR0aCAmJiBjb3VudDIgPD0gNTsgcG9zKyssIGNvdW50MisrKSB7CglpZiAoQ29sb3JDbXAobHBQW3Bvc10sIGxwQltwb3NdKSA+IGxEaXN0KQoJICBicmVhazsKICAgICAgfQogICAgICBpZiAoY291bnQyID4gNCkKCXJldHVybiBjb3VudDsKCiAgICAgIHBvcyAtPSBjb3VudDI7CiAgICB9CiAgfQoKICByZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyBJTlQgTVNSTEUzMl9Db21wcmVzc1JMRTRMaW5lKENvZGVjSW5mbyAqcGksIExQV09SRCBscFAsIExQV09SRCBscEMsIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaSwgQllURSAqbHBJbiwgTE9ORyBsRGlzdCwgSU5UIHgsIExQQllURSAqcHBPdXQsIERXT1JEICpscFNpemVJbWFnZSkKewogIExQQllURSBscE91dCA9ICpwcE91dDsKICBJTlQgICAgY291bnQsIHBvczsKICBXT1JEICAgY2xyMSwgY2xyMjsKCiAgLyogdHJ5IHRvIGVuY29kZSBhcyBtYW55IHBpeGVsIGFzIHBvc3NpYmxlICovCiAgY291bnQgPSAxOwogIHBvcyAgID0geDsKICBjbHIxICA9IGxwQ1twb3MrK107CiAgaWYgKHBvcyA8IGxwYmktPmJpV2lkdGgpIHsKICAgIGNscjIgPSBscENbcG9zXTsKICAgIGZvciAoKytjb3VudDsgcG9zICsgMSA8IGxwYmktPmJpV2lkdGg7ICkgewogICAgICArK3BvczsKICAgICAgaWYgKENvbG9yQ21wKGNscjEsIGxwQ1twb3NdKSA+IGxEaXN0KQoJYnJlYWs7CiAgICAgIGNvdW50Kys7CiAgICAgIGlmIChwb3MgKyAxID49IGxwYmktPmJpV2lkdGgpCglicmVhazsKICAgICAgKytwb3M7CiAgICAgIGlmIChDb2xvckNtcChjbHIyLCBscENbcG9zXSkgPiBsRGlzdCkKCWJyZWFrOwogICAgICBjb3VudCsrOwogICAgfQogIH0KCiAgaWYgKGNvdW50IDwgNCkgewogICAgLyogYWRkIHNvbWUgcGl4ZWwgZm9yIGFic29sdXRpbmcgaWYgcG9zc2libGUgKi8KICAgIGNvdW50ICs9IGNvdW50RGlmZlJMRTQobHBQLCBscEMgLSAxLCBscEMsIHBvcy0xLCBsRGlzdCwgbHBiaS0+YmlXaWR0aCk7CgogICAgYXNzZXJ0KGNvdW50ID4gMCk7CgogICAgLyogY2hlY2sgZm9yIG5lYXIgZW5kIG9mIGxpbmUgKi8KICAgIGlmICh4ICsgY291bnQgPiBscGJpLT5iaVdpZHRoKQogICAgICBjb3VudCA9IGxwYmktPmJpV2lkdGggLSB4OwoKICAgIC8qIGFic29sdXRlIHBpeGVsKHMpIGluIGdyb3VwcyBvZiBhdGxlYXN0IDMgYW5kIG1heGltYWwgMjU0IHBpeGVsICovCiAgICB3aGlsZSAoY291bnQgPiAyKSB7CiAgICAgIElOVCAgaTsKICAgICAgSU5UICBzaXplICAgICAgID0gbWluKGNvdW50LCAyNTQpOwogICAgICBpbnQgIGJ5dGVzICAgICAgPSAoKHNpemUgKyAxKSAmICh+MSkpIC8gMjsKICAgICAgQk9PTCBleHRyYV9ieXRlID0gYnl0ZXMgJiAweDAxOwoKICAgICAgKmxwU2l6ZUltYWdlICs9IDIgKyBieXRlcyArIGV4dHJhX2J5dGU7CiAgICAgIGFzc2VydCgoKCpscFNpemVJbWFnZSkgJSAyKSA9PSAwKTsKICAgICAgY291bnQgLT0gc2l6ZTsKICAgICAgKmxwT3V0KysgPSAwOwogICAgICAqbHBPdXQrKyA9IHNpemU7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBzaXplOyBpICs9IDIpIHsKCWNscjEgPSBwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXTsKCXgrKzsKCWlmIChpICsgMSA8IHNpemUpIHsKCSAgY2xyMiA9IHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCldOwoJICB4Kys7Cgl9IGVsc2UKCSAgY2xyMiA9IDA7CgoJKmxwT3V0KysgPSAoY2xyMSA8PCA0KSB8IGNscjI7CiAgICAgIH0KICAgICAgaWYgKGV4dHJhX2J5dGUpCgkqbHBPdXQrKyA9IDA7CiAgICB9CgogICAgaWYgKGNvdW50ID4gMCkgewogICAgICAvKiB0b28gbGVzcyBmb3IgYWJzb2x1dGluZyBzbyB3ZSBtdXN0IGVuY29kZSB0aGVtICovCiAgICAgIGFzc2VydChjb3VudCA8PSAyKTsKCiAgICAgICpscFNpemVJbWFnZSArPSAyOwogICAgICBjbHIxID0gcGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4KV07CiAgICAgIHgrKzsKICAgICAgaWYgKGNvdW50ID09IDIpIHsKCWNscjIgPSBwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXTsKCXgrKzsKICAgICAgfSBlbHNlCgljbHIyID0gMDsKICAgICAgKmxwT3V0KysgPSBjb3VudDsKICAgICAgKmxwT3V0KysgPSAoY2xyMSA8PCA0KSB8IGNscjI7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIGVuY29kZSBjb3VudCBwaXhlbChzKSAqLwogICAgY2xyMSA9ICgocGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4KV0gPDwgNCkgfAoJICAgIHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCArIDEpXSk7CgogICAgeCArPSBjb3VudDsKICAgIHdoaWxlIChjb3VudCA+IDApIHsKICAgICAgSU5UIHNpemUgPSBtaW4oY291bnQsIDI1NCk7CgogICAgICAqbHBTaXplSW1hZ2UgKz0gMjsKICAgICAgY291bnQgICAgLT0gc2l6ZTsKICAgICAgKmxwT3V0KysgID0gc2l6ZTsKICAgICAgKmxwT3V0KysgID0gY2xyMTsKICAgIH0KICB9CgogICpwcE91dCA9IGxwT3V0OwoKICByZXR1cm4geDsKfQoKc3RhdGljIElOVCBNU1JMRTMyX0NvbXByZXNzUkxFOExpbmUoQ29kZWNJbmZvICpwaSwgTFBXT1JEIGxwUCwgTFBXT1JEIGxwQywgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpLCBCWVRFICpscEluLCBMT05HIGxEaXN0LCBJTlQgeCwgTFBCWVRFICpwcE91dCwgRFdPUkQgKmxwU2l6ZUltYWdlKQp7CiAgTFBCWVRFIGxwT3V0ID0gKnBwT3V0OwogIElOVCAgICBjb3VudCwgcG9zOwogIFdPUkQgICBjbHI7CgogIGFzc2VydChscGJpLT5iaUJpdENvdW50IDw9IDgpOwogIGFzc2VydChscGJpLT5iaUNvbXByZXNzaW9uID09IEJJX1JHQik7CgogIC8qIHRyeSB0byBlbmNvZGUgYXMgbXVjaCBhcyBwb3NzaWJsZSAqLwogIHBvcyA9IHg7CiAgY2xyID0gbHBDW3BvcysrXTsKICBmb3IgKGNvdW50ID0gMTsgcG9zIDwgbHBiaS0+YmlXaWR0aDsgY291bnQrKykgewogICAgaWYgKENvbG9yQ21wKGNsciwgbHBDW3BvcysrXSkgPiBsRGlzdCkKICAgICAgYnJlYWs7CiAgfQoKICBpZiAoY291bnQgPCAyKSB7CiAgICAvKiBhZGQgc29tZSBtb3JlIHBpeGVscyBmb3IgYWJzb2x1dGluZyBpZiBwb3NzaWJsZSAqLwogICAgY291bnQgKz0gY291bnREaWZmUkxFOChscFAsIGxwQyAtIDEsIGxwQywgcG9zLTEsIGxEaXN0LCBscGJpLT5iaVdpZHRoKTsKCiAgICBhc3NlcnQoY291bnQgPiAwKTsKCiAgICAvKiBjaGVjayBmb3Igb3ZlciBlbmQgb2YgbGluZSAqLwogICAgaWYgKHggKyBjb3VudCA+IGxwYmktPmJpV2lkdGgpCiAgICAgIGNvdW50ID0gbHBiaS0+YmlXaWR0aCAtIHg7CgogICAgLyogYWJzb2x1dGUgcGl4ZWwocykgaW4gZ3JvdXBzIG9mIGF0bGVhc3QgMyBhbmQgbWF4aW1hbCAyNTUgcGl4ZWxzICovCiAgICB3aGlsZSAoY291bnQgPiAyKSB7CiAgICAgIElOVCAgaTsKICAgICAgSU5UICBzaXplICAgICAgID0gbWluKGNvdW50LCAyNTUpOwogICAgICBCT09MIGV4dHJhX2J5dGUgPSBzaXplICUgMjsKCiAgICAgICpscFNpemVJbWFnZSArPSAyICsgc2l6ZSArIGV4dHJhX2J5dGU7CiAgICAgIGNvdW50IC09IHNpemU7CiAgICAgICpscE91dCsrID0gMDsKICAgICAgKmxwT3V0KysgPSBzaXplOwogICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkqbHBPdXQrKyA9IHBpLT5wYWxldHRlX21hcFtHZXRSYXdQaXhlbChscGJpLGxwSW4seCldOwoJeCsrOwogICAgICB9CiAgICAgIGlmIChleHRyYV9ieXRlKQoJKmxwT3V0KysgPSAwOwogICAgfQogICAgaWYgKGNvdW50ID4gMCkgewogICAgICAvKiB0b28gbGVzcyBmb3IgYWJzb2x1dGluZyBzbyB3ZSBtdXN0IGVuY29kZSB0aGVtIGV2ZW4gaWYgaXQncyBleHBlbnNpdmUhICovCiAgICAgIGFzc2VydChjb3VudCA8PSAyKTsKCiAgICAgICpscFNpemVJbWFnZSArPSAyICogY291bnQ7CiAgICAgICpscE91dCsrID0gMTsKICAgICAgKmxwT3V0KysgPSBwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXTsKICAgICAgeCsrOwoKICAgICAgaWYgKGNvdW50ID09IDIpIHsKCSpscE91dCsrID0gMTsKCSpscE91dCsrID0gcGktPnBhbGV0dGVfbWFwW0dldFJhd1BpeGVsKGxwYmksbHBJbix4KV07Cgl4Kys7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgewogICAgLyogZW5jb2RlIGNvdW50IHBpeGVsKHMpICovCiAgICBjbHIgPSBwaS0+cGFsZXR0ZV9tYXBbR2V0UmF3UGl4ZWwobHBiaSxscEluLHgpXTsKCiAgICAvKiBvcHRpbWl6ZSBlbmQgb2YgbGluZSAqLwogICAgaWYgKHggKyBjb3VudCArIDEgPT0gbHBiaS0+YmlXaWR0aCkKICAgICAgY291bnQrKzsKCiAgICB4ICs9IGNvdW50OwogICAgd2hpbGUgKGNvdW50ID4gMCkgewogICAgICBJTlQgc2l6ZSA9IG1pbihjb3VudCwgMjU1KTsKCiAgICAgICpscFNpemVJbWFnZSArPSAyOwogICAgICBjb3VudCAgICAtPSBzaXplOwogICAgICAqbHBPdXQrKyAgPSBzaXplOwogICAgICAqbHBPdXQrKyAgPSBjbHI7CiAgICB9CiAgfQoKICAqcHBPdXQgPSBscE91dDsKCiAgcmV0dXJuIHg7Cn0KCkxSRVNVTFQgTVNSTEUzMl9Db21wcmVzc1JMRTQoQ29kZWNJbmZvICpwaSwgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwgTFBCWVRFIGxwSW4sIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0LCBMUEJZVEUgbHBPdXQsIEJPT0wgaXNLZXkpCnsKICBMUFdPUkQgbHBDOwogIExPTkcgICBsTGluZSwgbEluTGluZSwgbERpc3Q7CiAgTFBCWVRFIGxwT3V0U3RhcnQgPSBscE91dDsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQocGkgIT0gTlVMTCAmJiBscGJpT3V0ICE9IE5VTEwpOwogIGFzc2VydChscEluICE9IE5VTEwgJiYgbHBPdXQgIT0gTlVMTCk7CiAgYXNzZXJ0KHBpLT5wQ3VyRnJhbWUgIT0gTlVMTCk7CgogIGxwQyAgICAgID0gcGktPnBDdXJGcmFtZTsKICBsRGlzdCAgICA9IFFVQUxJVFlfdG9fRElTVChwaS0+ZHdRdWFsaXR5KTsKICBsSW5MaW5lICA9IERJQldJRFRIQllURVMoKmxwYmlJbik7CiAgbExpbmUgICAgPSBXSURUSEJZVEVTKGxwYmlPdXQtPmJpV2lkdGggKiAxNikgLyAyOwoKICBscGJpT3V0LT5iaVNpemVJbWFnZSA9IDA7CiAgaWYgKGlzS2V5KSB7CiAgICAvKiBrZXlmcmFtZSAtLSBjb252ZXJ0IGludGVybmFsIGZyYW1lIHRvIG91dHB1dCBmb3JtYXQgKi8KICAgIElOVCB4LCB5OwoKICAgIGZvciAoeSA9IDA7IHkgPCBscGJpT3V0LT5iaUhlaWdodDsgeSsrKSB7CiAgICAgIHggPSAwOwoKICAgICAgZG8gewoJeCA9IE1TUkxFMzJfQ29tcHJlc3NSTEU0TGluZShwaSwgTlVMTCwgbHBDLCBscGJpSW4sIGxwSW4sIGxEaXN0LCB4LAoJCQkJICAgICAmbHBPdXQsICZscGJpT3V0LT5iaVNpemVJbWFnZSk7CiAgICAgIH0gd2hpbGUgKHggPCBscGJpT3V0LT5iaVdpZHRoKTsKCiAgICAgIGxwQyAgICs9IGxMaW5lOwogICAgICBscEluICArPSBsSW5MaW5lOwoKICAgICAgLyogYWRkIEVPTCAtLSBlbmQgb2YgbGluZSAqLwogICAgICBscGJpT3V0LT5iaVNpemVJbWFnZSArPSAyOwogICAgICAqKExQV09SRClscE91dCA9IDA7CiAgICAgIGxwT3V0ICs9IHNpemVvZihXT1JEKTsKICAgICAgYXNzZXJ0KGxwT3V0ID09IChscE91dFN0YXJ0ICsgbHBiaU91dC0+YmlTaXplSW1hZ2UpKTsKICAgIH0KICB9IGVsc2UgewogICAgLyogZGVsdGEtZnJhbWUgLS0gY29tcHV0ZSBkZWx0YSBiZXR3ZWVuIGxhc3QgYW5kIHRoaXMgaW50ZXJuYWwgZnJhbWUgKi8KICAgIExQV09SRCBscFA7CiAgICBJTlQgICAgeCwgeTsKICAgIElOVCAgICBqdW1weCwganVtcHk7CgogICAgYXNzZXJ0KHBpLT5wUHJldkZyYW1lICE9IE5VTEwpOwoKICAgIGxwUCAgID0gcGktPnBQcmV2RnJhbWU7CiAgICBqdW1weSA9IDA7CiAgICBqdW1weCA9IC0xOwoKICAgIGZvciAoeSA9IDA7IHkgPCBscGJpT3V0LT5iaUhlaWdodDsgeSsrKSB7CiAgICAgIHggPSAwOwoKICAgICAgZG8gewoJSU5UIGNvdW50LCBwb3M7CgoJaWYgKGp1bXB4ID09IC0xKQoJICBqdW1weCA9IHg7Cglmb3IgKGNvdW50ID0gMCwgcG9zID0geDsgcG9zIDwgbHBiaU91dC0+YmlXaWR0aDsgcG9zKyssIGNvdW50KyspIHsKCSAgaWYgKENvbG9yQ21wKGxwUFtwb3NdLCBscENbcG9zXSkgPiBsRGlzdCkKCSAgICBicmVhazsKCX0KCglpZiAocG9zID09IGxwYmlPdXQtPmJpV2lkdGggJiYgY291bnQgPiA4KSB7CgkgIC8qIChjb3VudCA+IDgpIHNlY3VyZXMgdGhhdCB3ZSB3aWxsIHNhdmUgc3BhY2UgKi8KCSAganVtcHkrKzsKCSAgYnJlYWs7Cgl9IGVsc2UgaWYgKGp1bXB5IHx8IGp1bXB4ICE9IHBvcykgewoJICAvKiB0aW1lIHRvIGp1bXAgKi8KCSAgYXNzZXJ0KGp1bXB4ICE9IC0xKTsKCgkgIGlmIChwb3MgPCBqdW1weCkgewoJICAgIC8qIGNhbiBvbmx5IGp1bXAgaW4gcG9zaXRpdmUgZGlyZWN0aW9uIC0tIGp1bXAgdW50aWwgRU9MLCBFT0wgKi8KCSAgICBJTlQgdyA9IGxwYmlPdXQtPmJpV2lkdGggLSBqdW1weDsKCgkgICAgYXNzZXJ0KGp1bXB5ID4gMCk7CgkgICAgYXNzZXJ0KHcgPj0gNCk7CgoJICAgIGp1bXB4ID0gMDsKCSAgICBqdW1weS0tOwoJICAgIC8qIGlmICh3ICUgMjU1ID09IDIpIHRoZW4gZXF1YWwgY29zdHMKCSAgICAgKiBlbHNlIGlmICh3ICUgMjU1IDwgNCAmJiB3ZSBjb3VsZCBlbmNvZGUgYWxsKSB0aGVuIDIgYnl0ZXMgdG9vIGV4cGVuc2l2ZQoJICAgICAqIGVsc2UgaXQgd2lsbCBiZSBjaGVhcGVyCgkgICAgICovCgkgICAgd2hpbGUgKHcgPiAwKSB7CgkgICAgICBscGJpT3V0LT5iaVNpemVJbWFnZSArPSA0OwoJICAgICAgKmxwT3V0KysgPSAwOwoJICAgICAgKmxwT3V0KysgPSAyOwoJICAgICAgKmxwT3V0ICAgPSBtaW4odywgMjU1KTsKCSAgICAgIHcgICAgICAgLT0gKmxwT3V0Kys7CgkgICAgICAqbHBPdXQrKyA9IDA7CgkgICAgfQoJICAgIC8qIGFkZCBFT0wgLS0gZW5kIG9mIGxpbmUgKi8KCSAgICBscGJpT3V0LT5iaVNpemVJbWFnZSArPSAyOwoJICAgICooKExQV09SRClscE91dCkgPSAwOwoJICAgIGxwT3V0ICs9IHNpemVvZihXT1JEKTsKCSAgfQoKCSAgLyogRklYTUU6IGlmIChqdW1weSA9PSAwICYmIGNvdWxkIGVuY29kZSBhbGwpIHRoZW4ganVtcCB0b28gZXhwZW5zaXZlICovCgoJICAvKiB3cml0ZSBvdXQgcmVhbCBqdW1wKHMpICovCgkgIHdoaWxlIChqdW1weSB8fCBwb3MgIT0ganVtcHgpIHsKCSAgICBscGJpT3V0LT5iaVNpemVJbWFnZSArPSA0OwoJICAgICpscE91dCsrID0gMDsKCSAgICAqbHBPdXQrKyA9IDI7CgkgICAgKmxwT3V0ICAgPSBtaW4ocG9zIC0ganVtcHgsIDI1NSk7CgkgICAgeCAgICAgICArPSAqbHBPdXQ7CgkgICAganVtcHggICArPSAqbHBPdXQrKzsKCSAgICAqbHBPdXQgICA9IG1pbihqdW1weSwgMjU1KTsKCSAgICBqdW1weSAgIC09ICpscE91dCsrOwoJICB9CgoJICBqdW1weSA9IDA7Cgl9CgoJanVtcHggPSAtMTsKCglpZiAoeCA8IGxwYmlPdXQtPmJpV2lkdGgpIHsKCSAgLyogc2tpcHBlZCB0aGUgJ3NhbWUnIHRoaW5ncyBjb3JyZXNwb25kaW5nIHRvIHByZXZpb3VzIGZyYW1lICovCgkgIHggPSBNU1JMRTMyX0NvbXByZXNzUkxFNExpbmUocGksIGxwUCwgbHBDLCBscGJpSW4sIGxwSW4sIGxEaXN0LCB4LAoJCQkgICAgICAgJmxwT3V0LCAmbHBiaU91dC0+YmlTaXplSW1hZ2UpOwoJfQogICAgICB9IHdoaWxlICh4IDwgbHBiaU91dC0+YmlXaWR0aCk7CgogICAgICBscFAgICArPSBsTGluZTsKICAgICAgbHBDICAgKz0gbExpbmU7CiAgICAgIGxwSW4gICs9IGxJbkxpbmU7CgogICAgICBpZiAoanVtcHkgPT0gMCkgewoJYXNzZXJ0KGp1bXB4ID09IC0xKTsKCgkvKiBhZGQgRU9MIC0tIGVuZCBvZiBsaW5lICovCglscGJpT3V0LT5iaVNpemVJbWFnZSArPSAyOwoJKigoTFBXT1JEKWxwT3V0KSA9IDA7CiAgICAgICAgbHBPdXQgKz0gc2l6ZW9mKFdPUkQpOwoJYXNzZXJ0KGxwT3V0ID09IGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSk7CiAgICAgIH0KICAgIH0KCiAgICAvKiBhZGQgRU9MIC0tIHdpbGwgYmUgY2hhbmdlZCB0byBFT0kgKi8KICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDI7CiAgICAqKChMUFdPUkQpbHBPdXQpID0gMDsKICAgIGxwT3V0ICs9IHNpemVvZihXT1JEKTsKICB9CgogIC8qIGNoYW5nZSBFT0wgdG8gRU9JIC0tIGVuZCBvZiBpbWFnZSAqLwogIGxwT3V0Wy0xXSA9IDE7CiAgYXNzZXJ0KGxwT3V0ID09IChscE91dFN0YXJ0ICsgbHBiaU91dC0+YmlTaXplSW1hZ2UpKTsKCiAgcmV0dXJuIElDRVJSX09LOwp9CgpMUkVTVUxUIE1TUkxFMzJfQ29tcHJlc3NSTEU4KENvZGVjSW5mbyAqcGksIExQQklUTUFQSU5GT0hFQURFUiBscGJpSW4sIExQQllURSBscEluLCBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCwgTFBCWVRFIGxwT3V0LCBCT09MIGlzS2V5KQp7CiAgTFBXT1JEIGxwQzsKICBMT05HICAgbERpc3QsIGxJbkxpbmUsIGxMaW5lOwogIExQQllURSBscE91dFN0YXJ0ID0gbHBPdXQ7CgogIGFzc2VydChwaSAhPSBOVUxMICYmIGxwYmlPdXQgIT0gTlVMTCk7CiAgYXNzZXJ0KGxwSW4gIT0gTlVMTCAmJiBscE91dCAhPSBOVUxMKTsKICBhc3NlcnQocGktPnBDdXJGcmFtZSAhPSBOVUxMKTsKCiAgbHBDICAgICA9IHBpLT5wQ3VyRnJhbWU7CiAgbERpc3QgICA9IFFVQUxJVFlfdG9fRElTVChwaS0+ZHdRdWFsaXR5KTsKICBsSW5MaW5lID0gRElCV0lEVEhCWVRFUygqbHBiaUluKTsKICBsTGluZSAgID0gV0lEVEhCWVRFUyhscGJpT3V0LT5iaVdpZHRoICogMTYpIC8gMjsKCiAgbHBiaU91dC0+YmlTaXplSW1hZ2UgPSAwOwogIGlmIChpc0tleSkgewogICAgLyoga2V5ZnJhbWUgLS0gY29udmVydCBpbnRlcm5hbCBmcmFtZSB0byBvdXRwdXQgZm9ybWF0ICovCiAgICBJTlQgeCwgeTsKCiAgICBmb3IgKHkgPSAwOyB5IDwgbHBiaU91dC0+YmlIZWlnaHQ7IHkrKykgewogICAgICB4ID0gMDsKCiAgICAgIGRvIHsKCXggPSBNU1JMRTMyX0NvbXByZXNzUkxFOExpbmUocGksIE5VTEwsIGxwQywgbHBiaUluLCBscEluLCBsRGlzdCwgeCwKCQkJICAgICAmbHBPdXQsICZscGJpT3V0LT5iaVNpemVJbWFnZSk7Cglhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwogICAgICB9IHdoaWxlICh4IDwgbHBiaU91dC0+YmlXaWR0aCk7CgogICAgICBscEMgICs9IGxMaW5lOwogICAgICBscEluICs9IGxJbkxpbmU7CgogICAgICAvKiBhZGQgRU9MIC0tIGVuZCBvZiBsaW5lICovCiAgICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDI7CiAgICAgICooKExQV09SRClscE91dCkgPSAwOwogICAgICBscE91dCArPSBzaXplb2YoV09SRCk7CiAgICAgIGFzc2VydChscE91dCA9PSAobHBPdXRTdGFydCArIGxwYmlPdXQtPmJpU2l6ZUltYWdlKSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIGRlbHRhLWZyYW1lIC0tIGNvbXB1dGUgZGVsdGEgYmV0d2VlbiBsYXN0IGFuZCB0aGlzIGludGVybmFsIGZyYW1lICovCiAgICBMUFdPUkQgbHBQOwogICAgSU5UICAgIHgsIHk7CiAgICBJTlQgICAganVtcHgsIGp1bXB5OwoKICAgIGFzc2VydChwaS0+cFByZXZGcmFtZSAhPSBOVUxMKTsKCiAgICBscFAgICA9IHBpLT5wUHJldkZyYW1lOwogICAganVtcHggPSAtMTsKICAgIGp1bXB5ID0gMDsKCiAgICBmb3IgKHkgPSAwOyB5IDwgbHBiaU91dC0+YmlIZWlnaHQ7IHkrKykgewogICAgICB4ID0gMDsKCiAgICAgIGRvIHsKCUlOVCBjb3VudCwgcG9zOwoKCWlmIChqdW1weCA9PSAtMSkKCSAganVtcHggPSB4OwoJZm9yIChjb3VudCA9IDAsIHBvcyA9IHg7IHBvcyA8IGxwYmlPdXQtPmJpV2lkdGg7IHBvcysrLCBjb3VudCsrKSB7CgkgIGlmIChDb2xvckNtcChscFBbcG9zXSwgbHBDW3Bvc10pID4gbERpc3QpCgkgICAgYnJlYWs7Cgl9CgoJaWYgKHBvcyA9PSBscGJpT3V0LT5iaVdpZHRoICYmIGNvdW50ID4gNCkgewoJICAvKiAoY291bnQgPiA0KSBzZWN1cmVzIHRoYXQgd2Ugd2lsbCBzYXZlIHNwYWNlICovCgkgIGp1bXB5Kys7CgkgIGJyZWFrOwoJfSBlbHNlIGlmIChqdW1weSB8fCBqdW1weCAhPSBwb3MpIHsKCSAgLyogdGltZSB0byBqdW1wICovCgkgIGFzc2VydChqdW1weCAhPSAtMSk7CgoJICBpZiAocG9zIDwganVtcHgpIHsKCSAgICAvKiBjYW4gb25seSBqdW1wIGluIHBvc2l0aXZlIGRpcmVjdGlvbiAtLSBkbyBhIEVPTCB0aGVuIGp1bXAgKi8KCSAgICBhc3NlcnQoanVtcHkgPiAwKTsKCgkgICAganVtcHggPSAwOwoJICAgIGp1bXB5LS07CgoJICAgIC8qIGFkZCBFT0wgLS0gZW5kIG9mIGxpbmUgKi8KCSAgICBscGJpT3V0LT5iaVNpemVJbWFnZSArPSAyOwoJICAgICooKExQV09SRClscE91dCkgPSAwOwoJICAgIGxwT3V0ICs9IHNpemVvZihXT1JEKTsKCSAgICBhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwoJICB9CgoJICAvKiBGSVhNRTogaWYgKGp1bXB5ID09IDAgJiYgY291bGQgZW5jb2RlIGFsbCkgdGhlbiBqdW1wIHRvbyBleHBlbnNpdmUgKi8KCgkgIC8qIHdyaXRlIG91dCByZWFsIGp1bXAocykgKi8KCSAgd2hpbGUgKGp1bXB5IHx8IHBvcyAhPSBqdW1weCkgewoJICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICs9IDQ7CgkgICAgKmxwT3V0KysgPSAwOwoJICAgICpscE91dCsrID0gMjsKCSAgICAqbHBPdXQgICA9IG1pbihwb3MgLSBqdW1weCwgMjU1KTsKCSAgICBqdW1weCAgICs9ICpscE91dCsrOwoJICAgICpscE91dCAgID0gbWluKGp1bXB5LCAyNTUpOwoJICAgIGp1bXB5ICAgLT0gKmxwT3V0Kys7CgkgIH0KCSAgeCA9IHBvczsKCgkgIGp1bXB5ID0gMDsKCX0KCglqdW1weCA9IC0xOwoKCWlmICh4IDwgbHBiaU91dC0+YmlXaWR0aCkgewoJICAvKiBza2lwIHRoZSAnc2FtZScgdGhpbmdzIGNvcnJlc3BvbmRpbmcgdG8gcHJldmlvdXMgZnJhbWUgKi8KCSAgeCA9IE1TUkxFMzJfQ29tcHJlc3NSTEU4TGluZShwaSwgbHBQLCBscEMsIGxwYmlJbiwgbHBJbiwgbERpc3QsIHgsCgkJCSAgICAgICAmbHBPdXQsICZscGJpT3V0LT5iaVNpemVJbWFnZSk7CgkgIGFzc2VydChscE91dCA9PSAobHBPdXRTdGFydCArIGxwYmlPdXQtPmJpU2l6ZUltYWdlKSk7Cgl9CiAgICAgIH0gd2hpbGUgKHggPCBscGJpT3V0LT5iaVdpZHRoKTsKCiAgICAgIGxwUCAgKz0gbExpbmU7CiAgICAgIGxwQyAgKz0gbExpbmU7CiAgICAgIGxwSW4gKz0gbEluTGluZTsKCiAgICAgIGlmIChqdW1weSA9PSAwKSB7CgkvKiBhZGQgRU9MIC0tIGVuZCBvZiBsaW5lICovCglscGJpT3V0LT5iaVNpemVJbWFnZSArPSAyOwoJKigoTFBXT1JEKWxwT3V0KSA9IDA7CglscE91dCArPSBzaXplb2YoV09SRCk7Cglhc3NlcnQobHBPdXQgPT0gKGxwT3V0U3RhcnQgKyBscGJpT3V0LT5iaVNpemVJbWFnZSkpOwogICAgICB9CiAgICB9CgogICAgLyogYWRkIEVPTCAtLSB3aWxsIGJlIGNoYW5nZWQgdG8gRU9JICovCiAgICBscGJpT3V0LT5iaVNpemVJbWFnZSArPSAyOwogICAgKigoTFBXT1JEKWxwT3V0KSA9IDA7CiAgICBscE91dCArPSBzaXplb2YoV09SRCk7CiAgfQoKICAvKiBjaGFuZ2UgRU9MIHRvIEVPSSAtLSBlbmQgb2YgaW1hZ2UgKi8KICBscE91dFstMV0gPSAxOwogIGFzc2VydChscE91dCA9PSAobHBPdXRTdGFydCArIGxwYmlPdXQtPmJpU2l6ZUltYWdlKSk7CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIExSRVNVTFQgTVNSTEUzMl9EZWNvbXByZXNzUkxFNChDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmksCgkJCQkgICAgICBMUEJZVEUgbHBJbiwgTFBCWVRFIGxwT3V0KQp7CiAgaW50ICBieXRlc19wZXJfcGl4ZWw7CiAgaW50ICBsaW5lX3NpemU7CiAgaW50ICBwaXhlbF9wdHIgID0gMDsKICBpbnQgIGk7CiAgQk9PTCBiRW5kRmxhZyAgID0gRkFMU0U7CgogIGFzc2VydChwaSAhPSBOVUxMKTsKICBhc3NlcnQobHBiaSAhPSBOVUxMICYmIGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCKTsKICBhc3NlcnQobHBJbiAhPSBOVUxMICYmIGxwT3V0ICE9IE5VTEwpOwoKICBieXRlc19wZXJfcGl4ZWwgPSAobHBiaS0+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+cGFsZXR0ZV9tYXBbKGNvZGUxICYgMHgwRikgKiA0ICsgMF07CglCWVRFIGcyID0gcGktPnBhbGV0dGVfbWFwWyhjb2RlMSAmIDB4MEYpICogNCArIDFdOwoJQllURSByMiA9IHBpLT5wYWxldHRlX21hcFsoY29kZTEgJiAweDBGKSAqIDQgKyAyXTsKCglmb3IgKGkgPSAwOyBpIDwgY29kZTA7IGkrKykgewoJICBpZiAoKGkgJiAxKSA9PSAwKSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyICsgMF0gPSBiMTsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IGcxOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcjE7CgkgIH0gZWxzZSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyICsgMF0gPSBiMjsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IGcyOwoJICAgIGxwT3V0W3BpeGVsX3B0ciArIDJdID0gcjI7CgkgIH0KCSAgcGl4ZWxfcHRyICs9IGJ5dGVzX3Blcl9waXhlbDsKCX0KICAgICAgfQogICAgfQogIH0gd2hpbGUgKCEgYkVuZEZsYWcpOwoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCnN0YXRpYyBMUkVTVUxUIE1TUkxFMzJfRGVjb21wcmVzc1JMRTgoQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpLAoJCQkJICAgICAgTFBCWVRFIGxwSW4sIExQQllURSBscE91dCkKewogIGludCAgYnl0ZXNfcGVyX3BpeGVsOwogIGludCAgbGluZV9zaXplOwogIGludCAgcGl4ZWxfcHRyICA9IDA7CiAgQk9PTCBiRW5kRmxhZyAgID0gRkFMU0U7CgogIGFzc2VydChwaSAhPSBOVUxMKTsKICBhc3NlcnQobHBiaSAhPSBOVUxMICYmIGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCKTsKICBhc3NlcnQobHBJbiAhPSBOVUxMICYmIGxwT3V0ICE9IE5VTEwpOwoKICBieXRlc19wZXJfcGl4ZWwgPSAobHBiaS0+YmlCaXRDb3VudCArIDEpIC8gODsKICBsaW5lX3NpemUgICAgICAgPSBESUJXSURUSEJZVEVTKCpscGJpKTsKCiAgZG8gewogICAgQllURSBjb2RlMCwgY29kZTE7CgogICAgY29kZTAgPSAqbHBJbisrOwogICAgY29kZTEgPSAqbHBJbisrOwoKICAgIGlmIChjb2RlMCA9PSAwKSB7CiAgICAgIGludCAgZXh0cmFfYnl0ZTsKCiAgICAgIHN3aXRjaCAoY29kZTEpIHsKICAgICAgY2FzZSAgMDogLyogRU9MIC0gZW5kIG9mIGxpbmUgICovCglwaXhlbF9wdHIgPSAwOwoJbHBPdXQgKz0gbGluZV9zaXplOwoJYnJlYWs7CiAgICAgIGNhc2UgIDE6IC8qIEVPSSAtIGVuZCBvZiBpbWFnZSAqLwoJYkVuZEZsYWcgPSBUUlVFOwoJYnJlYWs7CiAgICAgIGNhc2UgIDI6IC8qIHNraXAgKi8KCXBpeGVsX3B0ciArPSAqbHBJbisrICogYnl0ZXNfcGVyX3BpeGVsOwoJbHBPdXQgICAgICs9ICpscEluKysgKiBsaW5lX3NpemU7CglpZiAocGl4ZWxfcHRyID49IGxwYmktPmJpV2lkdGggKiBieXRlc19wZXJfcGl4ZWwpIHsKCSAgcGl4ZWxfcHRyID0gMDsKCSAgbHBPdXQgICAgKz0gbGluZV9zaXplOwoJfQoJYnJlYWs7CiAgICAgIGRlZmF1bHQ6IC8qIGFic29sdXRlIG1vZGUgKi8KCWlmIChwaXhlbF9wdHIvYnl0ZXNfcGVyX3BpeGVsICsgY29kZTEgPiBscGJpLT5iaVdpZHRoKSB7CgkgIFdBUk4oImFib3J0ZWQgYWJzb2x1dGU6ICglZD0lZC8lZCslZCkgPiAlbGRcbiIscGl4ZWxfcHRyL2J5dGVzX3Blcl9waXhlbCArIGNvZGUxLHBpeGVsX3B0cixieXRlc19wZXJfcGl4ZWwsY29kZTEsbHBiaS0+YmlXaWR0aCk7CgkgIHJldHVybiBJQ0VSUl9FUlJPUjsKCX0KCWV4dHJhX2J5dGUgPSBjb2RlMSAmIDB4MDE7CgoJY29kZTAgPSBjb2RlMTsKCXdoaWxlIChjb2RlMC0tKSB7CgkgIGNvZGUxID0gKmxwSW4rKzsKCSAgaWYgKGJ5dGVzX3Blcl9waXhlbCA9PSAxKSB7CgkgICAgbHBPdXRbcGl4ZWxfcHRyXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMV07CgkgIH0gZWxzZSBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDIpIHsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAwXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDIgKyAwXTsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDIgKyAxXTsKCSAgfSBlbHNlIHsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAwXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAwXTsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAxXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAxXTsKCSAgICBscE91dFtwaXhlbF9wdHIgKyAyXSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAyXTsKCSAgfQoJICBwaXhlbF9wdHIgKz0gYnl0ZXNfcGVyX3BpeGVsOwoJfQoKCS8qIGlmIHRoZSBSTEUgY29kZSBpcyBvZGQsIHNraXAgYSBieXRlIGluIHRoZSBzdHJlYW0gKi8KCWlmIChleHRyYV9ieXRlKQoJICBscEluKys7CiAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAvKiBjb2RlZCBtb2RlICovCiAgICAgIGlmIChwaXhlbF9wdHIvYnl0ZXNfcGVyX3BpeGVsICsgY29kZTAgPiBscGJpLT5iaVdpZHRoKSB7CglXQVJOKCJhYm9ydGVkIGNvZGVkOiAoJWQ9JWQvJWQrJWQpID4gJWxkXG4iLHBpeGVsX3B0ci9ieXRlc19wZXJfcGl4ZWwgKyBjb2RlMSxwaXhlbF9wdHIsYnl0ZXNfcGVyX3BpeGVsLGNvZGUxLGxwYmktPmJpV2lkdGgpOwoJcmV0dXJuIElDRVJSX0VSUk9SOwogICAgICB9CgogICAgICBpZiAoYnl0ZXNfcGVyX3BpeGVsID09IDEpIHsKCWNvZGUxID0gcGktPnBhbGV0dGVfbWFwW2NvZGUxXTsKCXdoaWxlIChjb2RlMC0tKQoJICBscE91dFtwaXhlbF9wdHIrK10gPSBjb2RlMTsKICAgICAgfSBlbHNlIGlmIChieXRlc19wZXJfcGl4ZWwgPT0gMikgewoJQllURSBoaSA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDIgKyAwXTsKCUJZVEUgbG8gPSBwaS0+cGFsZXR0ZV9tYXBbY29kZTEgKiAyICsgMV07CgoJd2hpbGUgKGNvZGUwLS0pIHsKCSAgbHBPdXRbcGl4ZWxfcHRyICsgMF0gPSBoaTsKCSAgbHBPdXRbcGl4ZWxfcHRyICsgMV0gPSBsbzsKCSAgcGl4ZWxfcHRyICs9IGJ5dGVzX3Blcl9waXhlbDsKCX0KICAgICAgfSBlbHNlIHsKCUJZVEUgciA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAyXTsKCUJZVEUgZyA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAxXTsKCUJZVEUgYiA9IHBpLT5wYWxldHRlX21hcFtjb2RlMSAqIDQgKyAwXTsKCgl3aGlsZSAoY29kZTAtLSkgewoJICBscE91dFtwaXhlbF9wdHIgKyAwXSA9IGI7CgkgIGxwT3V0W3BpeGVsX3B0ciArIDFdID0gZzsKCSAgbHBPdXRbcGl4ZWxfcHRyICsgMl0gPSByOwoJICBwaXhlbF9wdHIgKz0gYnl0ZXNfcGVyX3BpeGVsOwoJfQogICAgICB9CiAgICB9CiAgfSB3aGlsZSAoISBiRW5kRmxhZyk7CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIENvZGVjSW5mbyogT3BlbihMUElDT1BFTiBpY2luZm8pCnsKICBDb2RlY0luZm8qIHBpID0gTlVMTDsKCiAgaWYgKGljaW5mbyA9PSBOVUxMKSB7CiAgICBUUkFDRSgiKE5VTEwpXG4iKTsKICAgIHJldHVybiAoTFBWT0lEKTB4RkZGRjAwMDA7CiAgfQoKICBUUkFDRSgiKCVwID0geyVsdSwweCUwOGxYKCU0LjRzKSwweCUwOGxYKCU0LjRzKSwweCVsWCwweCVsWCwuLi59KVxuIiwgaWNpbmZvLAoJaWNpbmZvLT5kd1NpemUsCWljaW5mby0+ZmNjVHlwZSwgKGNoYXIqKSZpY2luZm8tPmZjY1R5cGUsCglpY2luZm8tPmZjY0hhbmRsZXIsIChjaGFyKikmaWNpbmZvLT5mY2NIYW5kbGVyLAoJaWNpbmZvLT5kd1ZlcnNpb24saWNpbmZvLT5kd0ZsYWdzKTsKCiAgaWYgKGljaW5mby0+ZmNjVHlwZSAhPSBJQ1RZUEVfVklERU8pCiAgICByZXR1cm4gTlVMTDsKCiAgc3dpdGNoIChpY2luZm8tPmZjY0hhbmRsZXIpIHsKICBjYXNlIEZPVVJDQ19STEU6CiAgY2FzZSBGT1VSQ0NfUkxFNDoKICBjYXNlIEZPVVJDQ19STEU4OgogIGNhc2UgRk9VUkNDX01STEU6CiAgICBicmVhazsKICBjYXNlIG1taW9GT1VSQ0MoJ20nLCdyJywnbCcsJ2UnKToKICAgIGljaW5mby0+ZmNjSGFuZGxlciA9IEZPVVJDQ19NUkxFOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIFdBUk4oInVua25vd24gRk9VUkNDID0gMHglMDhsWCglNC40cykgIVxuIiwKCSBpY2luZm8tPmZjY0hhbmRsZXIsKGNoYXIqKSZpY2luZm8tPmZjY0hhbmRsZXIpOwogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBwaSA9IChDb2RlY0luZm8qKUxvY2FsQWxsb2MoTFBUUiwgc2l6ZW9mKENvZGVjSW5mbykpOwoKICBpZiAocGkgIT0gTlVMTCkgewogICAgcGktPmZjY0hhbmRsZXIgID0gaWNpbmZvLT5mY2NIYW5kbGVyOwoKICAgIHBpLT5iQ29tcHJlc3MgICA9IEZBTFNFOwogICAgcGktPmR3UXVhbGl0eSAgID0gTVNSTEUzMl9ERUZBVUxUUVVBTElUWTsKICAgIHBpLT5uUHJldkZyYW1lICA9IC0xOwogICAgcGktPnBQcmV2RnJhbWUgID0gcGktPnBDdXJGcmFtZSA9IE5VTEw7CgogICAgcGktPmJEZWNvbXByZXNzID0gRkFMU0U7CiAgICBwaS0+cGFsZXR0ZV9tYXAgPSBOVUxMOwogIH0KCiAgaWNpbmZvLT5kd0Vycm9yID0gKHBpICE9IE5VTEwgPyBJQ0VSUl9PSyA6IElDRVJSX01FTU9SWSk7CgogIHJldHVybiBwaTsKfQoKc3RhdGljIExSRVNVTFQgQ2xvc2UoQ29kZWNJbmZvICpwaSkKewogIFRSQUNFKCIoJXApXG4iLCBwaSk7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIGlmIChwaS0+cFByZXZGcmFtZSAhPSBOVUxMIHx8IHBpLT5wQ3VyRnJhbWUgIT0gTlVMTCkKICAgIENvbXByZXNzRW5kKHBpKTsKCiAgTG9jYWxGcmVlKChITE9DQUwpcGkpOwogIHJldHVybiAxOwp9CgpzdGF0aWMgTFJFU1VMVCBHZXRJbmZvKENvZGVjSW5mbyAqcGksIElDSU5GTyAqaWNpbmZvLCBEV09SRCBkd1NpemUpCnsKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGljaW5mbyA9PSBOVUxMKQogICAgcmV0dXJuIHNpemVvZihJQ0lORk8pOwogIGlmIChkd1NpemUgPCBzaXplb2YoSUNJTkZPKSkKICAgIHJldHVybiAwOwoKICBpY2luZm8tPmR3U2l6ZSAgICAgICA9IHNpemVvZihJQ0lORk8pOwogIGljaW5mby0+ZmNjVHlwZSAgICAgID0gc3RyZWFtdHlwZVZJREVPOwogIGljaW5mby0+ZmNjSGFuZGxlciAgID0gKHBpICE9IE5VTEwgPyBwaS0+ZmNjSGFuZGxlciA6IEZPVVJDQ19NUkxFKTsKICBpY2luZm8tPmR3RmxhZ3MgICAgICA9IFZJRENGX1FVQUxJVFkgfCBWSURDRl9URU1QT1JBTCB8IFZJRENGX0NSVU5DSCB8IFZJRENGX0ZBU1RURU1QT1JBTEM7CiAgaWNpbmZvLT5kd1ZlcnNpb24gICAgPSBNU1JMRTMyX1ZFUlNJT047CiAgaWNpbmZvLT5kd1ZlcnNpb25JQ00gPSAweDAxMDQwMDAwOyAvKiBWZXJzaW9uIDEuNCBidWlsZCAwICovCgogIExvYWRXaWRlU3RyaW5nKElEU19OQU1FLCBpY2luZm8tPnN6TmFtZSwgc2l6ZW9mKGljaW5mby0+c3pOYW1lKSk7CiAgTG9hZFdpZGVTdHJpbmcoSURTX0RFU0NSSVBUSU9OLCBpY2luZm8tPnN6RGVzY3JpcHRpb24sIHNpemVvZihpY2luZm8tPnN6RGVzY3JpcHRpb24pKTsKCiAgcmV0dXJuIHNpemVvZihJQ0lORk8pOwp9CgpzdGF0aWMgTFJFU1VMVCBTZXRRdWFsaXR5KENvZGVjSW5mbyAqcGksIExPTkcgbFF1YWxpdHkpCnsKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICBpZiAobFF1YWxpdHkgPT0gLTEpCiAgICBsUXVhbGl0eSA9IE1TUkxFMzJfREVGQVVMVFFVQUxJVFk7CiAgZWxzZSBpZiAoSUNRVUFMSVRZX0xPVyA+IGxRdWFsaXR5IHx8IGxRdWFsaXR5ID4gSUNRVUFMSVRZX0hJR0gpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CgogIHBpLT5kd1F1YWxpdHkgPSAoRFdPUkQpbFF1YWxpdHk7CgogIHJldHVybiBJQ0VSUl9PSzsKfQoKc3RhdGljIExSRVNVTFQgQ29uZmlndXJlKENvZGVjSW5mbyAqcGksIEhXTkQgaFduZCkKewogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIEZJWE1FICovCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBBYm91dChDb2RlY0luZm8gKnBpLCBIV05EIGhXbmQpCnsKICBDSEFSIHN6VGl0bGVbMjBdOwogIENIQVIgc3pBYm91dFsxMjhdOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KE1TUkxFMzJfaE1vZHVsZSAhPSAwKTsKCiAgTG9hZFN0cmluZ0EoTVNSTEUzMl9oTW9kdWxlLCBJRFNfTkFNRSwgc3pUaXRsZSwgc2l6ZW9mKHN6VGl0bGUpKTsKICBMb2FkU3RyaW5nQShNU1JMRTMyX2hNb2R1bGUsIElEU19BQk9VVCwgc3pBYm91dCwgc2l6ZW9mKHN6QWJvdXQpKTsKCiAgTWVzc2FnZUJveEEoaFduZCwgc3pBYm91dCwgc3pUaXRsZSwgTUJfT0t8TUJfSUNPTklORk9STUFUSU9OKTsKCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0dldEZvcm1hdChDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJCSBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIExSRVNVTFQgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIscGksbHBiaUluLGxwYmlPdXQpOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KHBpICE9IE5VTEwpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzIC0tIG5lZWQgYXRsZWFzdCBpbnB1dCBmb3JtYXQgKi8KICBpZiAobHBiaUluID09IE5VTEwpIHsKICAgIGlmIChscGJpT3V0ICE9IE5VTEwpCiAgICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKICAgIHJldHVybiAwOwogIH0KCiAgLyogaGFuZGxlIHVuc3VwcG9ydGVkIGlucHV0IGZvcm1hdCAqLwogIGlmIChDb21wcmVzc1F1ZXJ5KHBpLCBscGJpSW4sIE5VTEwpICE9IElDRVJSX09LKQogICAgcmV0dXJuIChscGJpT3V0ID09IE5VTEwgPyBJQ0VSUl9CQURGT1JNQVQgOiAwKTsKCiAgYXNzZXJ0KDAgPCBscGJpSW4tPmJpQml0Q291bnQgJiYgbHBiaUluLT5iaUJpdENvdW50IDw9IDgpOwoKICBzd2l0Y2ggKHBpLT5mY2NIYW5kbGVyKSB7CiAgY2FzZSBGT1VSQ0NfUkxFNDoKICAgIHNpemUgPSAxIDw8IDQ7CiAgICBicmVhazsKICBjYXNlIEZPVVJDQ19STEU4OgogICAgc2l6ZSA9IDEgPDwgODsKICAgIGJyZWFrOwogIGNhc2UgRk9VUkNDX1JMRToKICBjYXNlIEZPVVJDQ19NUkxFOgogICAgc2l6ZSA9IChscGJpSW4tPmJpQml0Q291bnQgPD0gNCA/IDEgPDwgNCA6IDEgPDwgOCk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgcmV0dXJuIElDRVJSX0VSUk9SOwogIH0KCiAgaWYgKGxwYmlJbi0+YmlDbHJVc2VkICE9IDApCiAgICBzaXplID0gbHBiaUluLT5iaUNsclVzZWQ7CgogIHNpemUgPSBzaXplb2YoQklUTUFQSU5GT0hFQURFUikgKyBzaXplICogc2l6ZW9mKFJHQlFVQUQpOwoKICBpZiAobHBiaU91dCAhPSBOVUxMKSB7CiAgICBscGJpT3V0LT5iaVNpemUgICAgICAgICAgPSBzaXplb2YoQklUTUFQSU5GT0hFQURFUik7CiAgICBscGJpT3V0LT5iaVdpZHRoICAgICAgICAgPSBscGJpSW4tPmJpV2lkdGg7CiAgICBscGJpT3V0LT5iaUhlaWdodCAgICAgICAgPSBscGJpSW4tPmJpSGVpZ2h0OwogICAgbHBiaU91dC0+YmlQbGFuZXMgICAgICAgID0gMTsKICAgIGlmIChwaS0+ZmNjSGFuZGxlciA9PSBGT1VSQ0NfUkxFNCB8fAoJbHBiaUluLT5iaUJpdENvdW50IDw9IDQpIHsKICAgICAgbHBiaU91dC0+YmlDb21wcmVzc2lvbiA9IEJJX1JMRTQ7CiAgICAgIGxwYmlPdXQtPmJpQml0Q291bnQgICAgPSA0OwogICAgfSBlbHNlIHsKICAgICAgbHBiaU91dC0+YmlDb21wcmVzc2lvbiA9IEJJX1JMRTg7CiAgICAgIGxwYmlPdXQtPmJpQml0Q291bnQgICAgPSA4OwogICAgfQogICAgbHBiaU91dC0+YmlTaXplSW1hZ2UgICAgID0gTVNSTEUzMl9HZXRNYXhDb21wcmVzc2VkU2l6ZShscGJpT3V0KTsKICAgIGxwYmlPdXQtPmJpWFBlbHNQZXJNZXRlciA9IGxwYmlJbi0+YmlYUGVsc1Blck1ldGVyOwogICAgbHBiaU91dC0+YmlZUGVsc1Blck1ldGVyID0gbHBiaUluLT5iaVlQZWxzUGVyTWV0ZXI7CiAgICBpZiAobHBiaUluLT5iaUNsclVzZWQgPT0gMCkKICAgICAgc2l6ZSA9IDE8PGxwYmlJbi0+YmlCaXRDb3VudDsKICAgIGVsc2UKICAgICAgc2l6ZSA9IGxwYmlJbi0+YmlDbHJVc2VkOwogICAgbHBiaU91dC0+YmlDbHJVc2VkICAgICAgID0gbWluKHNpemUsIDEgPDwgbHBiaU91dC0+YmlCaXRDb3VudCk7CiAgICBscGJpT3V0LT5iaUNsckltcG9ydGFudCAgPSAwOwoKICAgIG1lbWNweSgoTFBCWVRFKWxwYmlPdXQgKyBscGJpT3V0LT5iaVNpemUsCgkgICAoY29uc3QgQllURSopbHBiaUluICsgbHBiaUluLT5iaVNpemUsIGxwYmlPdXQtPmJpQ2xyVXNlZCAqIHNpemVvZihSR0JRVUFEKSk7CgogICAgcmV0dXJuIElDRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIHNpemU7Cn0KCnN0YXRpYyBMUkVTVUxUIENvbXByZXNzR2V0U2l6ZShDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJICAgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLHBpLGxwYmlJbixscGJpT3V0KTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyIC0tIG5lZWQgYXRsZWFzdCBvbmUgZm9ybWF0ICovCiAgaWYgKGxwYmlJbiA9PSBOVUxMICYmIGxwYmlPdXQgPT0gTlVMTCkKICAgIHJldHVybiAwOwogIC8qIGNoZWNrIGlmIHRoZSBnaXZlbiBmb3JtYXQgaXMgc3VwcG9ydGVkICovCiAgaWYgKENvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgbHBiaU91dCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gMDsKCiAgLyogdGhlIHdvcnN0IGNhc2UgaXMgY29kaW5nIHRoZSBjb21wbGV0ZSBpbWFnZSBpbiBhYnNvbHV0ZSBtb2RlLiAqLwogIGlmIChscGJpSW4pCiAgICByZXR1cm4gTVNSTEUzMl9HZXRNYXhDb21wcmVzc2VkU2l6ZShscGJpSW4pOwogIGVsc2UKICAgIHJldHVybiBNU1JMRTMyX0dldE1heENvbXByZXNzZWRTaXplKGxwYmlPdXQpOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc1F1ZXJ5KENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIG5lZWQgYXRsZWFzdCBvbmUgZm9ybWF0ICovCiAgaWYgKGxwYmlJbiA9PSBOVUxMICYmIGxwYmlPdXQgPT0gTlVMTCkKICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKCiAgLyogY2hlY2sgaW5wdXQgZm9ybWF0IGlmIGdpdmVuICovCiAgaWYgKGxwYmlJbiAhPSBOVUxMKSB7CiAgICBpZiAoIWlzU3VwcG9ydGVkRElCKGxwYmlJbikpCiAgICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CgogICAgLyogZm9yIDQtYml0IG5lZWQgYW4gZXZlbiB3aWR0aCAqLwogICAgaWYgKGxwYmlJbi0+YmlCaXRDb3VudCA8PSA0ICYmIChscGJpSW4tPmJpV2lkdGggJSAyKSkKICAgICAgcmV0dXJuIElDRVJSX0JBREZPUk1BVDsKCiAgICBpZiAocGktPmZjY0hhbmRsZXIgPT0gRk9VUkNDX1JMRTQgJiYgbHBiaUluLT5iaUJpdENvdW50ID4gNCkKICAgICAgcmV0dXJuIElDRVJSX1VOU1VQUE9SVEVEOwogICAgZWxzZSBpZiAobHBiaUluLT5iaUJpdENvdW50ID4gOCkKICAgICAgcmV0dXJuIElDRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgLyogY2hlY2sgb3V0cHV0IGZvcm1hdCBpZiBnaXZlbiAqLwogIGlmIChscGJpT3V0ICE9IE5VTEwpIHsKICAgIGlmICghaXNTdXBwb3J0ZWRNUkxFKGxwYmlPdXQpKQogICAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwoKICAgIGlmIChscGJpSW4gIT0gTlVMTCkgewogICAgICBpZiAobHBiaUluLT5iaVdpZHRoICAhPSBscGJpT3V0LT5iaVdpZHRoKQoJcmV0dXJuIElDRVJSX1VOU1VQUE9SVEVEOwogICAgICBpZiAobHBiaUluLT5iaUhlaWdodCAhPSBscGJpT3V0LT5iaUhlaWdodCkKCXJldHVybiBJQ0VSUl9VTlNVUFBPUlRFRDsKICAgICAgaWYgKGxwYmlJbi0+YmlCaXRDb3VudCA+IGxwYmlPdXQtPmJpQml0Q291bnQpCglyZXR1cm4gSUNFUlJfVU5TVVBQT1JURUQ7CiAgICB9CiAgfQoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCnN0YXRpYyBMUkVTVUxUIENvbXByZXNzQmVnaW4oQ29kZWNJbmZvICpwaSwgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpSW4sCgkJCSAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KQp7CiAgY29uc3QgUkdCUVVBRCAqcmdiSW47CiAgY29uc3QgUkdCUVVBRCAqcmdiT3V0OwogIFVJTlQgICBpOwogIHNpemVfdCBzaXplOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIixwaSxscGJpSW4sbHBiaU91dCk7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgLS0gbmVlZCBib3RoIGZvcm1hdHMgKi8KICBpZiAobHBiaUluID09IE5VTEwgfHwgbHBiaU91dCA9PSBOVUxMKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwogIC8qIEFuZCBib3RoIG11c3QgYmUgc3VwcG9ydGVkICovCiAgaWYgKENvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgbHBiaU91dCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwoKICAvKiBGSVhNRTogY2Fubm90IGNvbXByZXNzIGFuZCBkZWNvbXByZXNzIGF0IHNhbWUgdGltZSEgKi8KICBpZiAocGktPmJEZWNvbXByZXNzKSB7CiAgICBGSVhNRSgiY2Fubm90IGNvbXByZXNzIGFuZCBkZWNvbXByZXNzIGF0IHNhbWUgdGltZSFcbiIpOwogICAgcmV0dXJuIElDRVJSX0VSUk9SOwogIH0KCiAgaWYgKHBpLT5iQ29tcHJlc3MpCiAgICBDb21wcmVzc0VuZChwaSk7CgogIHNpemUgPSBXSURUSEJZVEVTKGxwYmlPdXQtPmJpV2lkdGggKiAxNikgLyAyICogbHBiaU91dC0+YmlIZWlnaHQ7CiAgcGktPnBQcmV2RnJhbWUgPSAoTFBXT1JEKUdsb2JhbEFsbG9jUHRyKEdQVFIsIHNpemUgKiBzaXplb2YoV09SRCkpOwogIGlmIChwaS0+cFByZXZGcmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIElDRVJSX01FTU9SWTsKICBwaS0+cEN1ckZyYW1lID0gKExQV09SRClHbG9iYWxBbGxvY1B0cihHUFRSLCBzaXplICogc2l6ZW9mKFdPUkQpKTsKICBpZiAocGktPnBDdXJGcmFtZSA9PSBOVUxMKSB7CiAgICBDb21wcmVzc0VuZChwaSk7CiAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwogIH0KICBwaS0+blByZXZGcmFtZSA9IC0xOwogIHBpLT5iQ29tcHJlc3MgID0gVFJVRTsKCiAgcmdiSW4gID0gKGNvbnN0IFJHQlFVQUQqKSgoY29uc3QgQllURSopbHBiaUluICArIGxwYmlJbi0+YmlTaXplKTsKICByZ2JPdXQgPSAoY29uc3QgUkdCUVVBRCopKChjb25zdCBCWVRFKilscGJpT3V0ICsgbHBiaU91dC0+YmlTaXplKTsKCiAgc3dpdGNoIChscGJpT3V0LT5iaUJpdENvdW50KSB7CiAgY2FzZSA0OgogIGNhc2UgODoKICAgIHBpLT5wYWxldHRlX21hcCA9IChMUEJZVEUpTG9jYWxBbGxvYyhMUFRSLCBscGJpSW4tPmJpQ2xyVXNlZCk7CiAgICBpZiAocGktPnBhbGV0dGVfbWFwID09IE5VTEwpIHsKICAgICAgQ29tcHJlc3NFbmQocGkpOwogICAgICByZXR1cm4gSUNFUlJfTUVNT1JZOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBscGJpSW4tPmJpQ2xyVXNlZDsgaSsrKSB7CiAgICAgIHBpLT5wYWxldHRlX21hcFtpXSA9IE1TUkxFMzJfR2V0TmVhcmVzdFBhbGV0dGVJbmRleChscGJpT3V0LT5iaUNsclVzZWQsIHJnYk91dCwgcmdiSW5baV0pOwogICAgfQogICAgYnJlYWs7CiAgfTsKCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzcyhDb2RlY0luZm8gKnBpLCBJQ0NPTVBSRVNTKiBscGljLCBEV09SRCBkd1NpemUpCnsKICBpbnQgaTsKCiAgVFJBQ0UoIiglcCwlcCwlbHUpXG4iLHBpLGxwaWMsZHdTaXplKTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscGljID09IE5VTEwgfHwgZHdTaXplIDwgc2l6ZW9mKElDQ09NUFJFU1MpKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwogIGlmICghbHBpYy0+bHBiaU91dHB1dCB8fCAhbHBpYy0+bHBPdXRwdXQgfHwKICAgICAgIWxwaWMtPmxwYmlJbnB1dCAgfHwgIWxwaWMtPmxwSW5wdXQpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CgogIFRSQUNFKCJscGljPXsweCVsWCwlcCwlcCwlcCwlcCwlcCwlcCwlbGQsJWx1LCVsdSwlcCwlcH1cbiIsbHBpYy0+ZHdGbGFncyxscGljLT5scGJpT3V0cHV0LGxwaWMtPmxwT3V0cHV0LGxwaWMtPmxwYmlJbnB1dCxscGljLT5scElucHV0LGxwaWMtPmxwY2tpZCxscGljLT5scGR3RmxhZ3MsbHBpYy0+bEZyYW1lTnVtLGxwaWMtPmR3RnJhbWVTaXplLGxwaWMtPmR3UXVhbGl0eSxscGljLT5scGJpUHJldixscGljLT5scFByZXYpOwoKICBpZiAoISBwaS0+YkNvbXByZXNzKSB7CiAgICBMUkVTVUxUIGhyID0gQ29tcHJlc3NCZWdpbihwaSwgbHBpYy0+bHBiaUlucHV0LCBscGljLT5scGJpT3V0cHV0KTsKICAgIGlmIChociAhPSBJQ0VSUl9PSykKICAgICAgcmV0dXJuIGhyOwogIH0gZWxzZSBpZiAoQ29tcHJlc3NRdWVyeShwaSwgbHBpYy0+bHBiaUlucHV0LCBscGljLT5scGJpT3V0cHV0KSAhPSBJQ0VSUl9PSykKICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CgogIGlmIChscGljLT5sRnJhbWVOdW0gPj0gcGktPm5QcmV2RnJhbWUgKyAxKSB7CiAgICAvKiB3ZSBjb250aW51ZSBpbiB0aGUgc2VxdWVuY2Ugc28gd2UgbmVlZCB0byBpbml0aWFsaXplIAogICAgICogb3VyIGludGVybmFsIGZyYW1lZGF0YSAqLwoKICAgIGNvbXB1dGVJbnRlcm5hbEZyYW1lKHBpLCBscGljLT5scGJpSW5wdXQsIGxwaWMtPmxwSW5wdXQpOwogIH0gZWxzZSBpZiAobHBpYy0+bEZyYW1lTnVtID09IHBpLT5uUHJldkZyYW1lKSB7CiAgICAvKiBPb3BzLCBjb21wcmVzcyBzYW1lIGZyYW1lIGFnYWluID8gT2theSwgYXMgeW91IHdpc2guCiAgICAgKiBObyBuZWVkIHRvIHJlY29tcHV0ZSBpbnRlcm5hbCBmcmFtZWRhdGEsIGJlY2F1c2Ugd2Ugb25seSBzd2FwcGVkIGJ1ZmZlcnMgKi8KICAgIExQV09SRCBwVG1wID0gcGktPnBQcmV2RnJhbWU7CgogICAgcGktPnBQcmV2RnJhbWUgPSBwaS0+cEN1ckZyYW1lOwogICAgcGktPnBDdXJGcmFtZSAgPSBwVG1wOwogIH0gZWxzZSBpZiAoKGxwaWMtPmR3RmxhZ3MgJiBJQ0NPTVBSRVNTX0tFWUZSQU1FKSA9PSAwKSB7CiAgICBMUFdPUkQgcFRtcDsKCiAgICBXQVJOKCI6IHByZXY9JWxkIGN1cj0lbGQgZ29uZSBiYWNrPyAtLSB1bnRlc3RlZFxuIixwaS0+blByZXZGcmFtZSxscGljLT5sRnJhbWVOdW0pOwogICAgaWYgKGxwaWMtPmxwYmlQcmV2ID09IE5VTEwgfHwgbHBpYy0+bHBQcmV2ID09IE5VTEwpCiAgICAgIHJldHVybiBJQ0VSUl9HT1RPS0VZRlJBTUU7IC8qIE5lZWQgYSBrZXlmcmFtZSBpZiB5b3UgZ28gYmFjayAqLwogICAgaWYgKENvbXByZXNzUXVlcnkocGksIGxwaWMtPmxwYmlQcmV2LCBscGljLT5scGJpT3V0cHV0KSAhPSBJQ0VSUl9PSykKICAgICAgcmV0dXJuIElDRVJSX0JBREZPUk1BVDsKCiAgICBXQVJOKCI6IHByZXY9JWxkIGN1cj0lbGQgY29tcHV0ZSBzd2FwcGVkIC0tIHVudGVzdGVkXG4iLHBpLT5uUHJldkZyYW1lLGxwaWMtPmxGcmFtZU51bSk7CiAgICBjb21wdXRlSW50ZXJuYWxGcmFtZShwaSwgbHBpYy0+bHBiaVByZXYsIGxwaWMtPmxwUHJldik7CgogICAgLyogc3dhcCBidWZmZXJzIGZvciBjdXJyZW50IGFuZCBwcmV2aW91cyBmcmFtZSAqLwogICAgLyogRG9uJ3QgZnJlZSBhbmQgYWxsb2MgbmV3IC0tIGNvc3RzIHRvIG11Y2ggdGltZSBhbmQgdGhleSBhcmUgb2YgZXF1YWwgc2l6ZSAhICovCiAgICBwVG1wID0gcGktPnBQcmV2RnJhbWU7CiAgICBwaS0+cFByZXZGcmFtZSA9IHBpLT5wQ3VyRnJhbWU7CiAgICBwaS0+cEN1ckZyYW1lICA9IHBUbXA7CiAgICBwaS0+blByZXZGcmFtZSA9IGxwaWMtPmxGcmFtZU51bTsKICB9CgogIGZvciAoaSA9IDA7IGkgPCAzOyBpKyspIHsKICAgIFNldFF1YWxpdHkocGksIGxwaWMtPmR3UXVhbGl0eSk7CgogICAgbHBpYy0+bHBiaU91dHB1dC0+YmlTaXplSW1hZ2UgPSAwOwoKICAgIGlmIChscGljLT5scGJpT3V0cHV0LT5iaUJpdENvdW50ID09IDQpCiAgICAgIE1TUkxFMzJfQ29tcHJlc3NSTEU0KHBpLCBscGljLT5scGJpSW5wdXQsIChMUEJZVEUpbHBpYy0+bHBJbnB1dCwKCQkgICBscGljLT5scGJpT3V0cHV0LCAoTFBCWVRFKWxwaWMtPmxwT3V0cHV0LCAobHBpYy0+ZHdGbGFncyAmIElDQ09NUFJFU1NfS0VZRlJBTUUpICE9IDApOwogICAgZWxzZQogICAgICBNU1JMRTMyX0NvbXByZXNzUkxFOChwaSwgbHBpYy0+bHBiaUlucHV0LCAoTFBCWVRFKWxwaWMtPmxwSW5wdXQsCgkJICAgbHBpYy0+bHBiaU91dHB1dCwgKExQQllURSlscGljLT5scE91dHB1dCwgKGxwaWMtPmR3RmxhZ3MgJiBJQ0NPTVBSRVNTX0tFWUZSQU1FKSAhPSAwKTsKCiAgICBpZiAobHBpYy0+ZHdGcmFtZVNpemUgPT0gMCB8fAoJbHBpYy0+bHBiaU91dHB1dC0+YmlTaXplSW1hZ2UgPCBscGljLT5kd0ZyYW1lU2l6ZSkKICAgICAgYnJlYWs7CgogICAgaWYgKCgqbHBpYy0+bHBkd0ZsYWdzICYgSUNDT01QUkVTU19LRVlGUkFNRSkgPT0gMCkgewogICAgICBpZiAobHBpYy0+bHBiaU91dHB1dC0+YmlCaXRDb3VudCA9PSA0KQoJTVNSTEUzMl9Db21wcmVzc1JMRTQocGksIGxwaWMtPmxwYmlJbnB1dCwgKExQQllURSlscGljLT5scElucHV0LAoJCQkgICAgIGxwaWMtPmxwYmlPdXRwdXQsIChMUEJZVEUpbHBpYy0+bHBPdXRwdXQsIFRSVUUpOwogICAgICBlbHNlCglNU1JMRTMyX0NvbXByZXNzUkxFOChwaSwgbHBpYy0+bHBiaUlucHV0LCAoTFBCWVRFKWxwaWMtPmxwSW5wdXQsCgkJCSAgICAgbHBpYy0+bHBiaU91dHB1dCwgKExQQllURSlscGljLT5scE91dHB1dCwgVFJVRSk7CgogICAgICBpZiAobHBpYy0+ZHdGcmFtZVNpemUgPT0gMCB8fAoJICBscGljLT5scGJpT3V0cHV0LT5iaVNpemVJbWFnZSA8IGxwaWMtPmR3RnJhbWVTaXplKSB7CglXQVJOKCJzd2l0Y2hlZCB0byBrZXlmcmFtZSwgd2FzIHNtYWxsIGVub3VnaCFcbiIpOwoJKmxwaWMtPmxwZHdGbGFncyB8PSBJQ0NPTVBSRVNTX0tFWUZSQU1FOwoJKmxwaWMtPmxwY2tpZCAgICA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmJpdHMsCgkJCQkgICAgICAgU3RyZWFtRnJvbUZPVVJDQygqbHBpYy0+bHBja2lkKSk7CglicmVhazsKICAgICAgfQogICAgfQoKICAgIGlmIChscGljLT5kd1F1YWxpdHkgPCAxMDAwKQogICAgICBicmVhazsKCiAgICBscGljLT5kd1F1YWxpdHkgLT0gMTAwMDsgLyogcmVkdWNlIHF1YWxpdHkgYnkgMTAlICovCiAgfQoKICB7IC8qIHN3YXAgYnVmZmVyIGZvciBjdXJyZW50IGFuZCBwcmV2aW91cyBmcmFtZSAqLwogICAgLyogRG9uJ3QgZnJlZSBhbmQgYWxsb2MgbmV3IC0tIGNvc3RzIHRvIG11Y2ggdGltZSBhbmQgdGhleSBhcmUgb2YgZXF1YWwgc2l6ZSAhICovCiAgICByZWdpc3RlciBMUFdPUkQgcFRtcCA9IHBpLT5wUHJldkZyYW1lOwoKICAgIHBpLT5wUHJldkZyYW1lID0gcGktPnBDdXJGcmFtZTsKICAgIHBpLT5wQ3VyRnJhbWUgID0gcFRtcDsKICAgIHBpLT5uUHJldkZyYW1lID0gbHBpYy0+bEZyYW1lTnVtOwogIH0KCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBDb21wcmVzc0VuZChDb2RlY0luZm8gKnBpKQp7CiAgVFJBQ0UoIiglcClcbiIscGkpOwoKICBpZiAocGkgIT0gTlVMTCkgewogICAgaWYgKHBpLT5wUHJldkZyYW1lICE9IE5VTEwpCiAgICAgIEdsb2JhbEZyZWVQdHIocGktPnBQcmV2RnJhbWUpOwogICAgaWYgKHBpLT5wQ3VyRnJhbWUgIT0gTlVMTCkKICAgICAgR2xvYmFsRnJlZVB0cihwaS0+cEN1ckZyYW1lKTsKICAgIHBpLT5wUHJldkZyYW1lID0gTlVMTDsKICAgIHBpLT5wQ3VyRnJhbWUgID0gTlVMTDsKICAgIHBpLT5uUHJldkZyYW1lID0gLTE7CiAgICBwaS0+YkNvbXByZXNzICA9IEZBTFNFOwogIH0KCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzR2V0Rm9ybWF0KENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkJICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPdXQpCnsKICBEV09SRCBzaXplOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIixwaSxscGJpSW4sbHBiaU91dCk7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIGlmIChscGJpSW4gPT0gTlVMTCkKICAgIHJldHVybiAobHBiaU91dCAhPSBOVUxMID8gSUNFUlJfQkFEUEFSQU0gOiAwKTsKCiAgaWYgKERlY29tcHJlc3NRdWVyeShwaSwgbHBiaUluLCBOVUxMKSAhPSBJQ0VSUl9PSykKICAgIHJldHVybiAobHBiaU91dCAhPSBOVUxMID8gSUNFUlJfQkFERk9STUFUIDogMCk7CgogIHNpemUgPSBscGJpSW4tPmJpU2l6ZTsKCiAgaWYgKGxwYmlJbi0+YmlCaXRDb3VudCA8PSA4KQogICAgc2l6ZSArPSBscGJpSW4tPmJpQ2xyVXNlZCAqIHNpemVvZihSR0JRVUFEKTsKCiAgaWYgKGxwYmlPdXQgIT0gTlVMTCkgewogICAgbWVtY3B5KGxwYmlPdXQsIGxwYmlJbiwgc2l6ZSk7CiAgICBscGJpT3V0LT5iaUNvbXByZXNzaW9uICA9IEJJX1JHQjsKICAgIGxwYmlPdXQtPmJpU2l6ZUltYWdlICAgID0gRElCV0lEVEhCWVRFUygqbHBiaU91dCkgKiBscGJpT3V0LT5iaUhlaWdodDsKCiAgICByZXR1cm4gSUNFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIExSRVNVTFQgRGVjb21wcmVzc1F1ZXJ5KENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkgICAgICAgTFBDQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KQp7CiAgTFJFU1VMVCBociA9IElDRVJSX09LOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIixwaSxscGJpSW4sbHBiaU91dCk7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIG5lZWQgYXRsZWFzdCBvbmUgZm9ybWF0ICovCiAgaWYgKGxwYmlJbiA9PSBOVUxMICYmIGxwYmlPdXQgPT0gTlVMTCkKICAgIHJldHVybiBJQ0VSUl9CQURQQVJBTTsKCiAgLyogY2hlY2sgaW5wdXQgZm9ybWF0IGlmIGdpdmVuICovCiAgaWYgKGxwYmlJbiAhPSBOVUxMKSB7CiAgICBpZiAoIWlzU3VwcG9ydGVkTVJMRShscGJpSW4pKQogICAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwogIH0KCiAgLyogY2hlY2sgb3V0cHV0IGZvcm1hdCBpZiBnaXZlbiAqLwogIGlmIChscGJpT3V0ICE9IE5VTEwpIHsKICAgIGlmICghaXNTdXBwb3J0ZWRESUIobHBiaU91dCkpCiAgICAgIGhyID0gSUNFUlJfQkFERk9STUFUOwoKICAgIGlmIChscGJpSW4gIT0gTlVMTCkgewogICAgICBpZiAobHBiaUluLT5iaVdpZHRoICAhPSBscGJpT3V0LT5iaVdpZHRoKQoJaHIgPSBJQ0VSUl9VTlNVUFBPUlRFRDsKICAgICAgaWYgKGxwYmlJbi0+YmlIZWlnaHQgIT0gbHBiaU91dC0+YmlIZWlnaHQpCglociA9IElDRVJSX1VOU1VQUE9SVEVEOwogICAgICBpZiAobHBiaUluLT5iaUJpdENvdW50ID4gbHBiaU91dC0+YmlCaXRDb3VudCkKCWhyID0gSUNFUlJfVU5TVVBQT1JURUQ7CiAgICB9CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NCZWdpbihDb2RlY0luZm8gKnBpLCBMUENCSVRNQVBJTkZPSEVBREVSIGxwYmlJbiwKCQkJICAgICAgIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaU91dCkKewogIGNvbnN0IFJHQlFVQUQgKnJnYkluOwogIGNvbnN0IFJHQlFVQUQgKnJnYk91dDsKICBVSU5UICBpOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIixwaSxscGJpSW4sbHBiaU91dCk7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHBiaUluID09IE5VTEwgfHwgbHBiaU91dCA9PSBOVUxMKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwogIGlmIChEZWNvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgbHBiaU91dCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwoKICAvKiBGSVhNRTogY2Fubm90IGNvbXByZXNzIGFuZCBkZWNvbXByZXNzIGF0IGEgdGltZSEgKi8KICBpZiAocGktPmJDb21wcmVzcykgewogICAgRklYTUUoImNhbm5vdCBjb21wcmVzcyBhbmQgZGVjb21wcmVzcyBhdCBzYW1lIHRpbWUhXG4iKTsKICAgIHJldHVybiBJQ0VSUl9FUlJPUjsKICB9CgogIGlmIChwaS0+YkRlY29tcHJlc3MpCiAgICBEZWNvbXByZXNzRW5kKHBpKTsKCiAgcmdiSW4gID0gKGNvbnN0IFJHQlFVQUQqKSgoY29uc3QgQllURSopbHBiaUluICArIGxwYmlJbi0+YmlTaXplKTsKICByZ2JPdXQgPSAoY29uc3QgUkdCUVVBRCopKChjb25zdCBCWVRFKilscGJpT3V0ICsgbHBiaU91dC0+YmlTaXplKTsKCiAgc3dpdGNoIChscGJpT3V0LT5iaUJpdENvdW50KSB7CiAgY2FzZSA0OgogIGNhc2UgODoKICAgIHBpLT5wYWxldHRlX21hcCA9IChMUEJZVEUpTG9jYWxBbGxvYyhMUFRSLCBscGJpSW4tPmJpQ2xyVXNlZCk7CiAgICBpZiAocGktPnBhbGV0dGVfbWFwID09IE5VTEwpCiAgICAgIHJldHVybiBJQ0VSUl9NRU1PUlk7CgogICAgZm9yIChpID0gMDsgaSA8IGxwYmlJbi0+YmlDbHJVc2VkOyBpKyspIHsKICAgICAgcGktPnBhbGV0dGVfbWFwW2ldID0gTVNSTEUzMl9HZXROZWFyZXN0UGFsZXR0ZUluZGV4KGxwYmlPdXQtPmJpQ2xyVXNlZCwgcmdiT3V0LCByZ2JJbltpXSk7CiAgICB9CiAgICBicmVhazsKICBjYXNlIDE1OgogIGNhc2UgMTY6CiAgICBwaS0+cGFsZXR0ZV9tYXAgPSAoTFBCWVRFKUxvY2FsQWxsb2MoTFBUUiwgbHBiaUluLT5iaUNsclVzZWQgKiAyKTsKICAgIGlmIChwaS0+cGFsZXR0ZV9tYXAgPT0gTlVMTCkKICAgICAgcmV0dXJuIElDRVJSX01FTU9SWTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbHBiaUluLT5iaUNsclVzZWQ7IGkrKykgewogICAgICBXT1JEIGNvbG9yOwoKICAgICAgaWYgKGxwYmlPdXQtPmJpQml0Q291bnQgPT0gMTUpCgljb2xvciA9ICgocmdiSW5baV0ucmdiUmVkID4+IDMpIDw8IDEwKQoJICB8ICgocmdiSW5baV0ucmdiR3JlZW4gPj4gMykgPDwgNSkgfCAocmdiSW5baV0ucmdiQmx1ZSA+PiAzKTsKICAgICAgZWxzZQoJY29sb3IgPSAoKHJnYkluW2ldLnJnYlJlZCA+PiAzKSA8PCAxMSkKCSAgfCAoKHJnYkluW2ldLnJnYkdyZWVuID4+IDMpIDw8IDUpIHwgKHJnYkluW2ldLnJnYkJsdWUgPj4gMyk7CgogICAgICBwaS0+cGFsZXR0ZV9tYXBbaSAqIDIgKyAxXSA9IGNvbG9yID4+IDg7CiAgICAgIHBpLT5wYWxldHRlX21hcFtpICogMiArIDBdID0gY29sb3IgJiAweEZGOwogICAgfTsKICAgIGJyZWFrOwogIGNhc2UgMjQ6CiAgY2FzZSAzMjoKICAgIHBpLT5wYWxldHRlX21hcCA9IChMUEJZVEUpTG9jYWxBbGxvYyhMUFRSLCBscGJpSW4tPmJpQ2xyVXNlZCAqIHNpemVvZihSR0JRVUFEKSk7CiAgICBpZiAocGktPnBhbGV0dGVfbWFwID09IE5VTEwpCiAgICAgIHJldHVybiBJQ0VSUl9NRU1PUlk7CiAgICBtZW1jcHkocGktPnBhbGV0dGVfbWFwLCByZ2JJbiwgbHBiaUluLT5iaUNsclVzZWQgKiBzaXplb2YoUkdCUVVBRCkpOwogICAgYnJlYWs7CiAgfTsKCiAgcGktPmJEZWNvbXByZXNzID0gVFJVRTsKCiAgcmV0dXJuIElDRVJSX09LOwp9CgpzdGF0aWMgTFJFU1VMVCBEZWNvbXByZXNzKENvZGVjSW5mbyAqcGksIElDREVDT01QUkVTUyAqcGljLCBEV09SRCBkd1NpemUpCnsKICBUUkFDRSgiKCVwLCVwLCVsdSlcbiIscGkscGljLGR3U2l6ZSk7CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQocGkgIT0gTlVMTCk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAocGljID09IE5VTEwpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CiAgaWYgKHBpYy0+bHBiaUlucHV0ID09IE5VTEwgfHwgcGljLT5scElucHV0ID09IE5VTEwgfHwKICAgICAgcGljLT5scGJpT3V0cHV0ID09IE5VTEwgfHwgcGljLT5scE91dHB1dCA9PSBOVUxMKQogICAgcmV0dXJuIElDRVJSX0JBRFBBUkFNOwoKICAvKiBjaGVjayBmb3JtYXRzICovCiAgaWYgKCEgcGktPmJEZWNvbXByZXNzKSB7CiAgICBMUkVTVUxUIGhyID0gRGVjb21wcmVzc0JlZ2luKHBpLCBwaWMtPmxwYmlJbnB1dCwgcGljLT5scGJpT3V0cHV0KTsKICAgIGlmIChociAhPSBJQ0VSUl9PSykKICAgICAgcmV0dXJuIGhyOwogIH0gZWxzZSBpZiAoRGVjb21wcmVzc1F1ZXJ5KHBpLCBwaWMtPmxwYmlJbnB1dCwgcGljLT5scGJpT3V0cHV0KSAhPSBJQ0VSUl9PSykKICAgIHJldHVybiBJQ0VSUl9CQURGT1JNQVQ7CgogIGFzc2VydChwaWMtPmxwYmlJbnB1dC0+YmlXaWR0aCAgPT0gcGljLT5scGJpT3V0cHV0LT5iaVdpZHRoKTsKICBhc3NlcnQocGljLT5scGJpSW5wdXQtPmJpSGVpZ2h0ID09IHBpYy0+bHBiaU91dHB1dC0+YmlIZWlnaHQpOwoKICBwaWMtPmxwYmlPdXRwdXQtPmJpU2l6ZUltYWdlID0gRElCV0lEVEhCWVRFUygqcGljLT5scGJpT3V0cHV0KSAqIHBpYy0+bHBiaU91dHB1dC0+YmlIZWlnaHQ7CiAgaWYgKHBpYy0+bHBiaUlucHV0LT5iaUJpdENvdW50ID09IDQpCiAgICByZXR1cm4gTVNSTEUzMl9EZWNvbXByZXNzUkxFNChwaSwgcGljLT5scGJpT3V0cHV0LCBwaWMtPmxwSW5wdXQsIHBpYy0+bHBPdXRwdXQpOwogIGVsc2UKICAgIHJldHVybiBNU1JMRTMyX0RlY29tcHJlc3NSTEU4KHBpLCBwaWMtPmxwYmlPdXRwdXQsIHBpYy0+bHBJbnB1dCwgcGljLT5scE91dHB1dCk7Cn0KCnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NFbmQoQ29kZWNJbmZvICpwaSkKewogIFRSQUNFKCIoJXApXG4iLHBpKTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgcGktPmJEZWNvbXByZXNzID0gRkFMU0U7CgogIGlmIChwaS0+cGFsZXR0ZV9tYXAgIT0gTlVMTCkgewogICAgTG9jYWxGcmVlKChITE9DQUwpcGktPnBhbGV0dGVfbWFwKTsKICAgIHBpLT5wYWxldHRlX21hcCA9IE5VTEw7CiAgfQoKICByZXR1cm4gSUNFUlJfT0s7Cn0KCnN0YXRpYyBMUkVTVUxUIERlY29tcHJlc3NHZXRQYWxldHRlKENvZGVjSW5mbyAqcGksIExQQ0JJVE1BUElORk9IRUFERVIgbHBiaUluLAoJCQkJICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0KQp7CiAgaW50IHNpemU7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLHBpLGxwYmlJbixscGJpT3V0KTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChwaSAhPSBOVUxMKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscGJpSW4gPT0gTlVMTCB8fCBscGJpT3V0ID09IE5VTEwpCiAgICByZXR1cm4gSUNFUlJfQkFEUEFSQU07CgogIGlmIChEZWNvbXByZXNzUXVlcnkocGksIGxwYmlJbiwgbHBiaU91dCkgIT0gSUNFUlJfT0spCiAgICByZXR1cm4gSUNFUlJfQkFERk9STUFUOwoKICBpZiAobHBiaU91dC0+YmlCaXRDb3VudCA+IDgpCiAgICByZXR1cm4gSUNFUlJfRVJST1I7CgogIGlmIChscGJpSW4tPmJpQml0Q291bnQgPD0gOCkgewogICAgaWYgKGxwYmlJbi0+YmlDbHJVc2VkID4gMCkKICAgICAgc2l6ZSA9IGxwYmlJbi0+YmlDbHJVc2VkOwogICAgZWxzZQogICAgICBzaXplID0gKDEgPDwgbHBiaUluLT5iaUJpdENvdW50KTsKCiAgICBscGJpT3V0LT5iaUNsclVzZWQgPSBzaXplOwoKICAgIG1lbWNweSgoTFBCWVRFKWxwYmlPdXQgKyBscGJpT3V0LT5iaVNpemUsIChjb25zdCBCWVRFKilscGJpSW4gKyBscGJpSW4tPmJpU2l6ZSwgc2l6ZSAqIHNpemVvZihSR0JRVUFEKSk7CiAgfSAvKiBlbHNlIGNvdWxkIG5ldmVyIG9jY3VyICEgKi8KCiAgcmV0dXJuIElDRVJSX09LOwp9CgovKiBEcml2ZXJQcm9jIC0gZW50cnkgcG9pbnQgZm9yIGFuIGluc3RhbGxhYmxlIGRyaXZlciAqLwpMUkVTVUxUIENBTExCQUNLIE1TUkxFMzJfRHJpdmVyUHJvYyhEV09SRCBkd0RydklELCBIRFJWUiBoRHJ2LCBVSU5UIHVNc2csCgkJCQkgICAgTFBBUkFNIGxQYXJhbTEsIExQQVJBTSBsUGFyYW0yKQp7CiAgQ29kZWNJbmZvICpwaSA9IChDb2RlY0luZm8qKWR3RHJ2SUQ7CgogIFRSQUNFKCIoJXAsJXAsMHglMDRYLDB4JTA4bFgsMHglMDhsWClcbiIsIChMUFZPSUQpZHdEcnZJRCwgKExQVk9JRCloRHJ2LAoJdU1zZywgbFBhcmFtMSwgbFBhcmFtMik7CgogIHN3aXRjaCAodU1zZykgewogICAgLyogc3RhbmRhcmQgZHJpdmVyIG1lc3NhZ2VzICovCiAgY2FzZSBEUlZfTE9BRDoKICAgIHJldHVybiBEUlZDTkZfT0s7CiAgY2FzZSBEUlZfT1BFTjoKICAgIGlmIChsUGFyYW0yID09IDApCiAgICAgIHJldHVybiAoTFJFU1VMVCkweEZGRkYwMDAwOwogICAgZWxzZQogICAgICByZXR1cm4gKExSRVNVTFQpT3BlbigoSUNPUEVOKilsUGFyYW0yKTsKICBjYXNlIERSVl9DTE9TRToKICAgIGlmIChkd0RydklEICE9IDB4RkZGRjAwMDAgJiYgKExQVk9JRClkd0RydklEICE9IE5VTEwpCiAgICAgIENsb3NlKHBpKTsKICAgIHJldHVybiBEUlZDTkZfT0s7CiAgY2FzZSBEUlZfRU5BQkxFOgogIGNhc2UgRFJWX0RJU0FCTEU6CiAgICByZXR1cm4gRFJWQ05GX09LOwogIGNhc2UgRFJWX0ZSRUU6CiAgICByZXR1cm4gRFJWQ05GX09LOwogIGNhc2UgRFJWX1FVRVJZQ09ORklHVVJFOgogICAgcmV0dXJuIERSVkNORl9DQU5DRUw7IC8qIEZJWE1FICovCiAgY2FzZSBEUlZfQ09ORklHVVJFOgogICAgcmV0dXJuIERSVkNORl9PSzsgICAgIC8qIEZJWE1FICovCiAgY2FzZSBEUlZfSU5TVEFMTDoKICBjYXNlIERSVl9SRU1PVkU6CiAgICByZXR1cm4gRFJWQ05GX09LOwoKICAgIC8qIGluc3RhbGxhYmxlIGNvbXByZXNzaW9uIG1hbmFnZXIgbWVzc2FnZXMgKi8KICBjYXNlIElDTV9DT05GSUdVUkU6CiAgICBGSVhNRSgiSUNNX0NPTkZJR1VSRSAoJWxkKVxuIixsUGFyYW0xKTsKICAgIGlmIChsUGFyYW0xID09IC0xKQogICAgICByZXR1cm4gSUNFUlJfVU5TVVBQT1JURUQ7IC8qIEZJWE1FICovCiAgICBlbHNlCiAgICAgIHJldHVybiBDb25maWd1cmUocGksIChIV05EKWxQYXJhbTEpOwogIGNhc2UgSUNNX0FCT1VUOgogICAgaWYgKGxQYXJhbTEgPT0gLTEpCiAgICAgIHJldHVybiBJQ0VSUl9PSzsKICAgIGVsc2UKICAgICAgcmV0dXJuIEFib3V0KHBpLCAoSFdORClsUGFyYW0xKTsKICBjYXNlIElDTV9HRVRTVEFURToKICBjYXNlIElDTV9TRVRTVEFURToKICAgIHJldHVybiAwOyAvKiBubyBzdGF0ZSAqLwogIGNhc2UgSUNNX0dFVElORk86CiAgICByZXR1cm4gR2V0SW5mbyhwaSwgKElDSU5GTyopbFBhcmFtMSwgKERXT1JEKWxQYXJhbTIpOwogIGNhc2UgSUNNX0dFVERFRkFVTFRRVUFMSVRZOgogICAgaWYgKChMUFZPSUQpbFBhcmFtMSAhPSBOVUxMKSB7CiAgICAgICooKExQRFdPUkQpbFBhcmFtMSkgPSBNU1JMRTMyX0RFRkFVTFRRVUFMSVRZOwogICAgICByZXR1cm4gSUNFUlJfT0s7CiAgICB9CiAgICBicmVhazsKICBjYXNlIElDTV9HRVRRVUFMSVRZOgogICAgaWYgKChMUFZPSUQpbFBhcmFtMSAhPSBOVUxMKSB7CiAgICAgICooKExQRFdPUkQpbFBhcmFtMSkgPSBwaS0+ZHdRdWFsaXR5OwogICAgICByZXR1cm4gSUNFUlJfT0s7CiAgICB9CiAgICBicmVhazsKICBjYXNlIElDTV9TRVRRVUFMSVRZOgogICAgcmV0dXJuIFNldFF1YWxpdHkocGksICooTFBMT05HKWxQYXJhbTEpOwogICAgYnJlYWs7CiAgY2FzZSBJQ01fQ09NUFJFU1NfR0VUX0ZPUk1BVDoKICAgIHJldHVybiBDb21wcmVzc0dldEZvcm1hdChwaSwgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJICAgICAoTFBCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTIpOwogIGNhc2UgSUNNX0NPTVBSRVNTX0dFVF9TSVpFOgogICAgcmV0dXJuIENvbXByZXNzR2V0U2l6ZShwaSwgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJICAgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMik7CiAgY2FzZSBJQ01fQ09NUFJFU1NfUVVFUlk6CiAgICByZXR1cm4gQ29tcHJlc3NRdWVyeShwaSwgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTIpOwogIGNhc2UgSUNNX0NPTVBSRVNTX0JFR0lOOgogICAgcmV0dXJuIENvbXByZXNzQmVnaW4ocGksIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTEsCgkJCSAoTFBDQklUTUFQSU5GT0hFQURFUilsUGFyYW0yKTsKICBjYXNlIElDTV9DT01QUkVTUzoKICAgIHJldHVybiBDb21wcmVzcyhwaSwgKElDQ09NUFJFU1MqKWxQYXJhbTEsIChEV09SRClsUGFyYW0yKTsKICBjYXNlIElDTV9DT01QUkVTU19FTkQ6CiAgICByZXR1cm4gQ29tcHJlc3NFbmQocGkpOwogIGNhc2UgSUNNX0RFQ09NUFJFU1NfR0VUX0ZPUk1BVDoKICAgIHJldHVybiBEZWNvbXByZXNzR2V0Rm9ybWF0KHBpLCAoTFBDQklUTUFQSU5GT0hFQURFUilsUGFyYW0xLAoJCQkgICAgICAgKExQQklUTUFQSU5GT0hFQURFUilsUGFyYW0yKTsKICBjYXNlIElDTV9ERUNPTVBSRVNTX1FVRVJZOgogICAgcmV0dXJuIERlY29tcHJlc3NRdWVyeShwaSwgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJICAgKExQQ0JJVE1BUElORk9IRUFERVIpbFBhcmFtMik7CiAgY2FzZSBJQ01fREVDT01QUkVTU19CRUdJTjoKICAgIHJldHVybiBEZWNvbXByZXNzQmVnaW4ocGksIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTEsCgkJCSAgIChMUENCSVRNQVBJTkZPSEVBREVSKWxQYXJhbTIpOwogIGNhc2UgSUNNX0RFQ09NUFJFU1M6CiAgICByZXR1cm4gRGVjb21wcmVzcyhwaSwgKElDREVDT01QUkVTUyopbFBhcmFtMSwgKERXT1JEKWxQYXJhbTIpOwogIGNhc2UgSUNNX0RFQ09NUFJFU1NfRU5EOgogICAgcmV0dXJuIERlY29tcHJlc3NFbmQocGkpOwogIGNhc2UgSUNNX0RFQ09NUFJFU1NfU0VUX1BBTEVUVEU6CiAgICBGSVhNRSgiKC4uLikgLT4gU2V0UGFsZXR0ZSglcCwlcCwlcCk6IHN0dWIhXG4iLCBwaSwgKExQVk9JRClsUGFyYW0xLCAoTFBWT0lEKWxQYXJhbTIpOwogICAgcmV0dXJuIElDRVJSX1VOU1VQUE9SVEVEOwogIGNhc2UgSUNNX0RFQ09NUFJFU1NfR0VUX1BBTEVUVEU6CiAgICByZXR1cm4gRGVjb21wcmVzc0dldFBhbGV0dGUocGksIChMUEJJVE1BUElORk9IRUFERVIpbFBhcmFtMSwKCQkJCShMUEJJVE1BUElORk9IRUFERVIpbFBhcmFtMik7CiAgY2FzZSBJQ01fR0VUREVGQVVMVEtFWUZSQU1FUkFURToKICAgIGlmICgoTFBWT0lEKWxQYXJhbTEgIT0gTlVMTCkKICAgICAgKihMUERXT1JEKWxQYXJhbTEgPSAxNTsKICAgIHJldHVybiBJQ0VSUl9PSzsKICBkZWZhdWx0OgogICAgaWYgKHVNc2cgPCBEUlZfVVNFUikKICAgICAgcmV0dXJuIERlZkRyaXZlclByb2MoZHdEcnZJRCwgaERydiwgdU1zZywgbFBhcmFtMSwgbFBhcmFtMik7CiAgICBlbHNlCiAgICAgIEZJWE1FKCJVbmtub3duIG1lc3NhZ2UgdU1zZz0weCUwOFggbFBhcmFtMT0weCUwOGxYIGxQYXJhbTI9MHglMDhsWFxuIix1TXNnLGxQYXJhbTEsbFBhcmFtMik7CiAgfTsKCiAgcmV0dXJuIElDRVJSX1VOU1VQUE9SVEVEOwp9CgovKiBEbGxNYWluIC0gbGlicmFyeSBpbml0aWFsaXphdGlvbiBjb2RlICovCkJPT0wgV0lOQVBJIERsbE1haW4oSElOU1RBTkNFIGhNb2R1bGUsIERXT1JEIGR3UmVhc29uLCBMUFZPSUQgbHBSZXNlcnZlZCkKewogIFRSQUNFKCIoJXAsJWxkLCVwKVxuIiwoTFBWT0lEKWhNb2R1bGUsZHdSZWFzb24sbHBSZXNlcnZlZCk7CgogIHN3aXRjaCAoZHdSZWFzb24pIHsKICBjYXNlIERMTF9QUk9DRVNTX0FUVEFDSDoKICAgIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoaE1vZHVsZSk7CiAgICBNU1JMRTMyX2hNb2R1bGUgPSBoTW9kdWxlOwogICAgYnJlYWs7CgogIGNhc2UgRExMX1BST0NFU1NfREVUQUNIOgogICAgYnJlYWs7CiAgfTsKCiAgcmV0dXJuIFRSVUU7Cn0K