LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY25hbWUuYyx2IDEuOSAyMDAyLzA2LzI2IDIyOjE0OjA4IGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSAiZmNpbnQuaCIKCnN0YXRpYyBjb25zdCBGY09iamVjdFR5cGUgX0ZjQmFzZU9iamVjdFR5cGVzW10gPSB7CiAgICB7IEZDX0ZBTUlMWSwJRmNUeXBlU3RyaW5nLCB9LAogICAgeyBGQ19TVFlMRSwJCUZjVHlwZVN0cmluZywgfSwKICAgIHsgRkNfU0xBTlQsCQlGY1R5cGVJbnRlZ2VyLCB9LAogICAgeyBGQ19XRUlHSFQsCUZjVHlwZUludGVnZXIsIH0sCiAgICB7IEZDX1NJWkUsCQlGY1R5cGVEb3VibGUsIH0sCiAgICB7IEZDX0FTUEVDVCwJRmNUeXBlRG91YmxlLCB9LAogICAgeyBGQ19QSVhFTF9TSVpFLAlGY1R5cGVEb3VibGUsIH0sCiAgICB7IEZDX1NQQUNJTkcsCUZjVHlwZUludGVnZXIsIH0sCiAgICB7IEZDX0ZPVU5EUlksCUZjVHlwZVN0cmluZywgfSwKLyogICAgeyBGQ19DT1JFLAkJRmNUeXBlQm9vbCwgfSwgKi8KICAgIHsgRkNfQU5USUFMSUFTLAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19ISU5USU5HLAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19WRVJUSUNBTF9MQVlPVVQsICAgRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfQVVUT0hJTlQsCUZjVHlwZUJvb2wsIH0sCiAgICB7IEZDX0dMT0JBTF9BRFZBTkNFLCAgICBGY1R5cGVCb29sLCB9LAovKiAgICB7IEZDX1hMRkQsCQlGY1R5cGVTdHJpbmcsIH0sICovCiAgICB7IEZDX0ZJTEUsCQlGY1R5cGVTdHJpbmcsIH0sCiAgICB7IEZDX0lOREVYLAkJRmNUeXBlSW50ZWdlciwgfSwKICAgIHsgRkNfUkFTVEVSSVpFUiwJRmNUeXBlU3RyaW5nLCB9LAogICAgeyBGQ19PVVRMSU5FLAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19TQ0FMQUJMRSwJRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfRFBJLAkJRmNUeXBlRG91YmxlIH0sCiAgICB7IEZDX1JHQkEsCQlGY1R5cGVJbnRlZ2VyLCB9LAogICAgeyBGQ19TQ0FMRSwJCUZjVHlwZURvdWJsZSwgfSwKLyogICAgeyBGQ19SRU5ERVIsCUZjVHlwZUJvb2wsIH0sKi8KICAgIHsgRkNfTUlOU1BBQ0UsCUZjVHlwZUJvb2wsIH0sCiAgICB7IEZDX0NIQVJfV0lEVEgsCUZjVHlwZUludGVnZXIgfSwKICAgIHsgRkNfQ0hBUl9IRUlHSFQsCUZjVHlwZUludGVnZXIgfSwKICAgIHsgRkNfTUFUUklYLAlGY1R5cGVNYXRyaXggfSwKICAgIHsgRkNfQ0hBUlNFVCwJRmNUeXBlQ2hhclNldCB9LAogICAgeyBGQ19MQU5HLAkJRmNUeXBlU3RyaW5nIH0sCn07CgojZGVmaW5lIE5VTV9PQkpFQ1RfVFlQRVMgICAgKHNpemVvZiBfRmNCYXNlT2JqZWN0VHlwZXMgLyBzaXplb2YgX0ZjQmFzZU9iamVjdFR5cGVzWzBdKQoKdHlwZWRlZiBzdHJ1Y3QgX0ZjT2JqZWN0VHlwZUxpc3QgICAgRmNPYmplY3RUeXBlTGlzdDsKCnN0cnVjdCBfRmNPYmplY3RUeXBlTGlzdCB7CiAgICBjb25zdCBGY09iamVjdFR5cGVMaXN0ICAqbmV4dDsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZQkgICAgKnR5cGVzOwogICAgaW50CQkJICAgIG50eXBlczsKfTsKCnN0YXRpYyBjb25zdCBGY09iamVjdFR5cGVMaXN0IF9GY0Jhc2VPYmplY3RUeXBlc0xpc3QgPSB7CiAgICAwLAogICAgX0ZjQmFzZU9iamVjdFR5cGVzLAogICAgTlVNX09CSkVDVF9UWVBFUwp9OwoKc3RhdGljIGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QJKl9GY09iamVjdFR5cGVzID0gJl9GY0Jhc2VPYmplY3RUeXBlc0xpc3Q7CgpGY0Jvb2wKRmNOYW1lUmVnaXN0ZXJPYmplY3RUeXBlcyAoY29uc3QgRmNPYmplY3RUeXBlICp0eXBlcywgaW50IG50eXBlcykKewogICAgRmNPYmplY3RUeXBlTGlzdAkqbDsKCiAgICBsID0gKEZjT2JqZWN0VHlwZUxpc3QgKikgbWFsbG9jIChzaXplb2YgKEZjT2JqZWN0VHlwZUxpc3QpKTsKICAgIGlmICghbCkKCXJldHVybiBGY0ZhbHNlOwogICAgbC0+dHlwZXMgPSB0eXBlczsKICAgIGwtPm50eXBlcyA9IG50eXBlczsKICAgIGwtPm5leHQgPSBfRmNPYmplY3RUeXBlczsKICAgIF9GY09iamVjdFR5cGVzID0gbDsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY05hbWVVbnJlZ2lzdGVyT2JqZWN0VHlwZXMgKGNvbnN0IEZjT2JqZWN0VHlwZSAqdHlwZXMsIGludCBudHlwZXMpCnsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QJKmwsICoqcHJldjsKCiAgICBmb3IgKHByZXYgPSAmX0ZjT2JqZWN0VHlwZXM7IAoJIChsID0gKnByZXYpOyAKCSBwcmV2ID0gKGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QgKiopICYobC0+bmV4dCkpCiAgICB7CglpZiAobC0+dHlwZXMgPT0gdHlwZXMgJiYgbC0+bnR5cGVzID09IG50eXBlcykKCXsKCSAgICAqcHJldiA9IGwtPm5leHQ7CgkgICAgZnJlZSAoKHZvaWQgKikgbCk7CgkgICAgcmV0dXJuIEZjVHJ1ZTsKCX0KICAgIH0KICAgIHJldHVybiBGY0ZhbHNlOwp9Cgpjb25zdCBGY09iamVjdFR5cGUgKgpGY05hbWVHZXRPYmplY3RUeXBlIChjb25zdCBjaGFyICpvYmplY3QpCnsKICAgIGludAkJCSAgICBpOwogICAgY29uc3QgRmNPYmplY3RUeXBlTGlzdCAgKmw7CiAgICBjb25zdCBGY09iamVjdFR5cGUJICAgICp0OwogICAgCiAgICBmb3IgKGwgPSBfRmNPYmplY3RUeXBlczsgbDsgbCA9IGwtPm5leHQpCiAgICB7Cglmb3IgKGkgPSAwOyBpIDwgbC0+bnR5cGVzOyBpKyspCgl7CgkgICAgdCA9ICZsLT50eXBlc1tpXTsKCSAgICBpZiAoIXN0cmNtcCAob2JqZWN0LCB0LT5vYmplY3QpKQoJCXJldHVybiB0OwoJfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBjb25zdCBGY0NvbnN0YW50IF9GY0Jhc2VDb25zdGFudHNbXSA9IHsKICAgIHsgKEZjQ2hhcjggKikgImxpZ2h0IiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9MSUdIVCwgfSwKICAgIHsgKEZjQ2hhcjggKikgIm1lZGl1bSIsCSAgICAid2VpZ2h0IiwgICBGQ19XRUlHSFRfTUVESVVNLCB9LAogICAgeyAoRmNDaGFyOCAqKSAiZGVtaWJvbGQiLAkgICAgIndlaWdodCIsICAgRkNfV0VJR0hUX0RFTUlCT0xELCB9LAogICAgeyAoRmNDaGFyOCAqKSAiYm9sZCIsCSAgICAid2VpZ2h0IiwgICBGQ19XRUlHSFRfQk9MRCwgfSwKICAgIHsgKEZjQ2hhcjggKikgImJsYWNrIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9CTEFDSywgfSwKCiAgICB7IChGY0NoYXI4ICopICJyb21hbiIsCSAgICAic2xhbnQiLCAgICBGQ19TTEFOVF9ST01BTiwgfSwKICAgIHsgKEZjQ2hhcjggKikgIml0YWxpYyIsCSAgICAic2xhbnQiLCAgICBGQ19TTEFOVF9JVEFMSUMsIH0sCiAgICB7IChGY0NoYXI4ICopICJvYmxpcXVlIiwJICAgICJzbGFudCIsICAgIEZDX1NMQU5UX09CTElRVUUsIH0sCgogICAgeyAoRmNDaGFyOCAqKSAicHJvcG9ydGlvbmFsIiwgICAic3BhY2luZyIsICBGQ19QUk9QT1JUSU9OQUwsIH0sCiAgICB7IChGY0NoYXI4ICopICJtb25vIiwJICAgICJzcGFjaW5nIiwgIEZDX01PTk8sIH0sCiAgICB7IChGY0NoYXI4ICopICJjaGFyY2VsbCIsCSAgICAic3BhY2luZyIsICBGQ19DSEFSQ0VMTCwgfSwKCiAgICB7IChGY0NoYXI4ICopICJub25lIiwJICAgICJyZ2JhIiwJICAgIEZDX1JHQkFfTk9ORSB9LAogICAgeyAoRmNDaGFyOCAqKSAicmdiIiwJICAgICJyZ2JhIiwJICAgIEZDX1JHQkFfUkdCLCB9LAogICAgeyAoRmNDaGFyOCAqKSAiYmdyIiwJICAgICJyZ2JhIiwJICAgIEZDX1JHQkFfQkdSLCB9LAogICAgeyAoRmNDaGFyOCAqKSAidnJnYiIsCSAgICAicmdiYSIsCSAgICBGQ19SR0JBX1ZSR0IgfSwKICAgIHsgKEZjQ2hhcjggKikgInZiZ3IiLAkgICAgInJnYmEiLAkgICAgRkNfUkdCQV9WQkdSIH0sCn07CgojZGVmaW5lIE5VTV9GQ19DT05TVEFOVFMgICAoc2l6ZW9mIF9GY0Jhc2VDb25zdGFudHMvc2l6ZW9mIF9GY0Jhc2VDb25zdGFudHNbMF0pCgp0eXBlZGVmIHN0cnVjdCBfRmNDb25zdGFudExpc3QgRmNDb25zdGFudExpc3Q7CgpzdHJ1Y3QgX0ZjQ29uc3RhbnRMaXN0IHsKICAgIGNvbnN0IEZjQ29uc3RhbnRMaXN0ICAgICpuZXh0OwogICAgY29uc3QgRmNDb25zdGFudAkgICAgKmNvbnN0czsKICAgIGludAkJCSAgICBuY29uc3RzOwp9OwoKc3RhdGljIGNvbnN0IEZjQ29uc3RhbnRMaXN0IF9GY0Jhc2VDb25zdGFudExpc3QgPSB7CiAgICAwLAogICAgX0ZjQmFzZUNvbnN0YW50cywKICAgIE5VTV9GQ19DT05TVEFOVFMKfTsKCnN0YXRpYyBjb25zdCBGY0NvbnN0YW50TGlzdAkqX0ZjQ29uc3RhbnRzID0gJl9GY0Jhc2VDb25zdGFudExpc3Q7CgpGY0Jvb2wKRmNOYW1lUmVnaXN0ZXJDb25zdGFudHMgKGNvbnN0IEZjQ29uc3RhbnQgKmNvbnN0cywgaW50IG5jb25zdHMpCnsKICAgIEZjQ29uc3RhbnRMaXN0CSpsOwoKICAgIGwgPSAoRmNDb25zdGFudExpc3QgKikgbWFsbG9jIChzaXplb2YgKEZjQ29uc3RhbnRMaXN0KSk7CiAgICBpZiAoIWwpCglyZXR1cm4gRmNGYWxzZTsKICAgIGwtPmNvbnN0cyA9IGNvbnN0czsKICAgIGwtPm5jb25zdHMgPSBuY29uc3RzOwogICAgbC0+bmV4dCA9IF9GY0NvbnN0YW50czsKICAgIF9GY0NvbnN0YW50cyA9IGw7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNOYW1lVW5yZWdpc3RlckNvbnN0YW50cyAoY29uc3QgRmNDb25zdGFudCAqY29uc3RzLCBpbnQgbmNvbnN0cykKewogICAgY29uc3QgRmNDb25zdGFudExpc3QJKmwsICoqcHJldjsKCiAgICBmb3IgKHByZXYgPSAmX0ZjQ29uc3RhbnRzOyAKCSAobCA9ICpwcmV2KTsgCgkgcHJldiA9IChjb25zdCBGY0NvbnN0YW50TGlzdCAqKikgJihsLT5uZXh0KSkKICAgIHsKCWlmIChsLT5jb25zdHMgPT0gY29uc3RzICYmIGwtPm5jb25zdHMgPT0gbmNvbnN0cykKCXsKCSAgICAqcHJldiA9IGwtPm5leHQ7CgkgICAgZnJlZSAoKHZvaWQgKikgbCk7CgkgICAgcmV0dXJuIEZjVHJ1ZTsKCX0KICAgIH0KICAgIHJldHVybiBGY0ZhbHNlOwp9Cgpjb25zdCBGY0NvbnN0YW50ICoKRmNOYW1lR2V0Q29uc3RhbnQgKEZjQ2hhcjggKnN0cmluZykKewogICAgY29uc3QgRmNDb25zdGFudExpc3QgICAgKmw7CiAgICBpbnQJCQkgICAgaTsKICAgIAogICAgZm9yIChsID0gX0ZjQ29uc3RhbnRzOyBsOyBsID0gbC0+bmV4dCkKICAgIHsKCWZvciAoaSA9IDA7IGkgPCBsLT5uY29uc3RzOyBpKyspCgkgICAgaWYgKCFGY1N0ckNtcElnbm9yZUNhc2UgKHN0cmluZywgbC0+Y29uc3RzW2ldLm5hbWUpKQoJCXJldHVybiAmbC0+Y29uc3RzW2ldOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCkZjQm9vbApGY05hbWVDb25zdGFudCAoRmNDaGFyOCAqc3RyaW5nLCBpbnQgKnJlc3VsdCkKewogICAgY29uc3QgRmNDb25zdGFudAkqYzsKCiAgICBpZiAoKGMgPSBGY05hbWVHZXRDb25zdGFudChzdHJpbmcpKSkKICAgIHsKCSpyZXN1bHQgPSBjLT52YWx1ZTsKCXJldHVybiBGY1RydWU7CiAgICB9CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNCb29sCkZjTmFtZUJvb2wgKEZjQ2hhcjggKnYsIEZjQm9vbCAqcmVzdWx0KQp7CiAgICBjaGFyICAgIGMwLCBjMTsKCiAgICBjMCA9ICp2OwogICAgaWYgKGlzdXBwZXIgKGMwKSkKCWMwID0gdG9sb3dlciAoYzApOwogICAgaWYgKGMwID09ICd0JyB8fCBjMCA9PSAneScgfHwgYzAgPT0gJzEnKQogICAgewoJKnJlc3VsdCA9IEZjVHJ1ZTsKCXJldHVybiBGY1RydWU7CiAgICB9CiAgICBpZiAoYzAgPT0gJ2YnIHx8IGMwID09ICduJyB8fCBjMCA9PSAnMCcpCiAgICB7CgkqcmVzdWx0ID0gRmNGYWxzZTsKCXJldHVybiBGY1RydWU7CiAgICB9CiAgICBpZiAoYzAgPT0gJ28nKQogICAgewoJYzEgPSB2WzFdOwoJaWYgKGlzdXBwZXIgKGMxKSkKCSAgICBjMSA9IHRvbG93ZXIgKGMxKTsKCWlmIChjMSA9PSAnbicpCgl7CgkgICAgKnJlc3VsdCA9IEZjVHJ1ZTsKCSAgICByZXR1cm4gRmNUcnVlOwoJfQoJaWYgKGMxID09ICdmJykKCXsKCSAgICAqcmVzdWx0ID0gRmNGYWxzZTsKCSAgICByZXR1cm4gRmNUcnVlOwoJfQogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCnN0YXRpYyBGY1ZhbHVlCkZjTmFtZUNvbnZlcnQgKEZjVHlwZSB0eXBlLCBGY0NoYXI4ICpzdHJpbmcsIEZjTWF0cml4ICptKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gdHlwZTsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6CglpZiAoIUZjTmFtZUNvbnN0YW50IChzdHJpbmcsICZ2LnUuaSkpCgkgICAgdi51LmkgPSBhdG9pICgoY2hhciAqKSBzdHJpbmcpOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCXYudS5zID0gc3RyaW5nOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUJvb2w6CglpZiAoIUZjTmFtZUJvb2wgKHN0cmluZywgJnYudS5iKSkKCSAgICB2LnUuYiA9IEZjRmFsc2U7CglicmVhazsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJdi51LmQgPSBzdHJ0b2QgKChjaGFyICopIHN0cmluZywgMCk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJdi51Lm0gPSBtOwoJc3NjYW5mICgoY2hhciAqKSBzdHJpbmcsICIlbGcgJWxnICVsZyAlbGciLCAmbS0+eHgsICZtLT54eSwgJm0tPnl4LCAmbS0+eXkpOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6Cgl2LnUuYyA9IEZjTmFtZVBhcnNlQ2hhclNldCAoc3RyaW5nKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIHY7Cn0KCnN0YXRpYyBjb25zdCBGY0NoYXI4ICoKRmNOYW1lRmluZE5leHQgKGNvbnN0IEZjQ2hhcjggKmN1ciwgY29uc3QgY2hhciAqZGVsaW0sIEZjQ2hhcjggKnNhdmUsIEZjQ2hhcjggKmxhc3QpCnsKICAgIEZjQ2hhcjggICAgYzsKICAgIAogICAgd2hpbGUgKChjID0gKmN1cikpCiAgICB7CglpZiAoYyA9PSAnXFwnKQoJewoJICAgICsrY3VyOwoJICAgIGlmICghKGMgPSAqY3VyKSkKCQlicmVhazsKCX0KCWVsc2UgaWYgKHN0cmNociAoZGVsaW0sIGMpKQoJICAgIGJyZWFrOwoJKytjdXI7Cgkqc2F2ZSsrID0gYzsKICAgIH0KICAgICpzYXZlID0gMDsKICAgICpsYXN0ID0gKmN1cjsKICAgIGlmICgqY3VyKQoJY3VyKys7CiAgICByZXR1cm4gY3VyOwp9CgpGY1BhdHRlcm4gKgpGY05hbWVQYXJzZSAoY29uc3QgRmNDaGFyOCAqbmFtZSkKewogICAgRmNDaGFyOAkJKnNhdmU7CiAgICBGY1BhdHRlcm4JCSpwYXQ7CiAgICBkb3VibGUJCWQ7CiAgICBGY0NoYXI4CQkqZTsKICAgIEZjQ2hhcjgJCWRlbGltOwogICAgRmNWYWx1ZQkJdjsKICAgIEZjTWF0cml4CQltOwogICAgY29uc3QgRmNPYmplY3RUeXBlCSp0OwogICAgY29uc3QgRmNDb25zdGFudAkqYzsKCiAgICBzYXZlID0gbWFsbG9jIChzdHJsZW4gKChjaGFyICopIG5hbWUpICsgMSk7CiAgICBpZiAoIXNhdmUpCglnb3RvIGJhaWwwOwogICAgcGF0ID0gRmNQYXR0ZXJuQ3JlYXRlICgpOwogICAgaWYgKCFwYXQpCglnb3RvIGJhaWwxOwoKICAgIGZvciAoOzspCiAgICB7CgluYW1lID0gRmNOYW1lRmluZE5leHQgKG5hbWUsICItLDoiLCBzYXZlLCAmZGVsaW0pOwoJaWYgKHNhdmVbMF0pCgl7CgkgICAgaWYgKCFGY1BhdHRlcm5BZGRTdHJpbmcgKHBhdCwgRkNfRkFNSUxZLCBzYXZlKSkKCQlnb3RvIGJhaWwyOwoJfQoJaWYgKGRlbGltICE9ICcsJykKCSAgICBicmVhazsKICAgIH0KICAgIGlmIChkZWxpbSA9PSAnLScpCiAgICB7Cglmb3IgKDs7KQoJewoJICAgIG5hbWUgPSBGY05hbWVGaW5kTmV4dCAobmFtZSwgIi0sOiIsIHNhdmUsICZkZWxpbSk7CgkgICAgZCA9IHN0cnRvZCAoKGNoYXIgKikgc2F2ZSwgKGNoYXIgKiopICZlKTsKCSAgICBpZiAoZSAhPSBzYXZlKQoJICAgIHsKCQlpZiAoIUZjUGF0dGVybkFkZERvdWJsZSAocGF0LCBGQ19TSVpFLCBkKSkKCQkgICAgZ290byBiYWlsMjsKCSAgICB9CgkgICAgaWYgKGRlbGltICE9ICcsJykKCQlicmVhazsKCX0KICAgIH0KICAgIHdoaWxlIChkZWxpbSA9PSAnOicpCiAgICB7CgluYW1lID0gRmNOYW1lRmluZE5leHQgKG5hbWUsICI9XzoiLCBzYXZlLCAmZGVsaW0pOwoJaWYgKHNhdmVbMF0pCgl7CgkgICAgaWYgKGRlbGltID09ICc9JyB8fCBkZWxpbSA9PSAnXycpCgkgICAgewoJCXQgPSBGY05hbWVHZXRPYmplY3RUeXBlICgoY2hhciAqKSBzYXZlKTsKCQlmb3IgKDs7KQoJCXsKCQkgICAgbmFtZSA9IEZjTmFtZUZpbmROZXh0IChuYW1lLCAiOiwiLCBzYXZlLCAmZGVsaW0pOwoJCSAgICBpZiAodCkKCQkgICAgewoJCQl2ID0gRmNOYW1lQ29udmVydCAodC0+dHlwZSwgc2F2ZSwgJm0pOwoJCQlpZiAoIUZjUGF0dGVybkFkZCAocGF0LCB0LT5vYmplY3QsIHYsIEZjVHJ1ZSkpCgkJCXsKCQkJICAgIGlmICh2LnR5cGUgPT0gRmNUeXBlQ2hhclNldCkKCQkJCUZjQ2hhclNldERlc3Ryb3kgKChGY0NoYXJTZXQgKikgdi51LmMpOwoJCQkgICAgZ290byBiYWlsMjsKCQkJfQoJCQlpZiAodi50eXBlID09IEZjVHlwZUNoYXJTZXQpCgkJCSAgICBGY0NoYXJTZXREZXN0cm95ICgoRmNDaGFyU2V0ICopIHYudS5jKTsKCQkgICAgfQoJCSAgICBpZiAoZGVsaW0gIT0gJywnKQoJCQlicmVhazsKCQl9CgkgICAgfQoJICAgIGVsc2UKCSAgICB7CgkJaWYgKChjID0gRmNOYW1lR2V0Q29uc3RhbnQgKHNhdmUpKSkKCQl7CgkJICAgIGlmICghRmNQYXR0ZXJuQWRkSW50ZWdlciAocGF0LCBjLT5vYmplY3QsIGMtPnZhbHVlKSkKCQkJZ290byBiYWlsMjsKCQl9CgkgICAgfQoJfQogICAgfQoKICAgIGZyZWUgKHNhdmUpOwogICAgcmV0dXJuIHBhdDsKCmJhaWwyOgogICAgRmNQYXR0ZXJuRGVzdHJveSAocGF0KTsKYmFpbDE6CiAgICBmcmVlIChzYXZlKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQpzdGF0aWMgRmNCb29sCkZjTmFtZVVucGFyc2VTdHJpbmcgKEZjU3RyQnVmCSAgICAqYnVmLCAKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpzdHJpbmcsCgkJICAgICBjb25zdCBGY0NoYXI4ICAqZXNjYXBlKQp7CiAgICBGY0NoYXI4IGM7CiAgICB3aGlsZSAoKGMgPSAqc3RyaW5nKyspKQogICAgewoJaWYgKGVzY2FwZSAmJiBzdHJjaHIgKChjaGFyICopIGVzY2FwZSwgKGNoYXIpIGMpKQoJewoJICAgIGlmICghRmNTdHJCdWZDaGFyIChidWYsIGVzY2FwZVswXSkpCgkJcmV0dXJuIEZjRmFsc2U7Cgl9CglpZiAoIUZjU3RyQnVmQ2hhciAoYnVmLCBjKSkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNOYW1lVW5wYXJzZVZhbHVlIChGY1N0ckJ1ZgkqYnVmLAoJCSAgICBGY1ZhbHVlCXYsCgkJICAgIEZjQ2hhcjgJKmVzY2FwZSkKewogICAgRmNDaGFyOAl0ZW1wWzEwMjRdOwogICAgCiAgICBzd2l0Y2ggKHYudHlwZSkgewogICAgY2FzZSBGY1R5cGVWb2lkOgoJcmV0dXJuIEZjVHJ1ZTsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCXNwcmludGYgKChjaGFyICopIHRlbXAsICIlZCIsIHYudS5pKTsKCXJldHVybiBGY05hbWVVbnBhcnNlU3RyaW5nIChidWYsIHRlbXAsIDApOwogICAgY2FzZSBGY1R5cGVEb3VibGU6CglzcHJpbnRmICgoY2hhciAqKSB0ZW1wLCAiJWciLCB2LnUuZCk7CglyZXR1cm4gRmNOYW1lVW5wYXJzZVN0cmluZyAoYnVmLCB0ZW1wLCAwKTsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJcmV0dXJuIEZjTmFtZVVucGFyc2VTdHJpbmcgKGJ1Ziwgdi51LnMsIGVzY2FwZSk7CiAgICBjYXNlIEZjVHlwZUJvb2w6CglyZXR1cm4gRmNOYW1lVW5wYXJzZVN0cmluZyAoYnVmLCB2LnUuYiA/IChGY0NoYXI4ICopICJUcnVlIiA6IChGY0NoYXI4ICopICJGYWxzZSIsIDApOwogICAgY2FzZSBGY1R5cGVNYXRyaXg6CglzcHJpbnRmICgoY2hhciAqKSB0ZW1wLCAiJWcgJWcgJWcgJWciLCAKCQkgdi51Lm0tPnh4LCB2LnUubS0+eHksIHYudS5tLT55eCwgdi51Lm0tPnl5KTsKCXJldHVybiBGY05hbWVVbnBhcnNlU3RyaW5nIChidWYsIHRlbXAsIDApOwogICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJcmV0dXJuIEZjTmFtZVVucGFyc2VDaGFyU2V0IChidWYsIHYudS5jKTsKICAgIGNhc2UgRmNUeXBlRlRGYWNlOgoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIHJldHVybiBGY0ZhbHNlOwp9CgpzdGF0aWMgRmNCb29sCkZjTmFtZVVucGFyc2VWYWx1ZUxpc3QgKEZjU3RyQnVmCSpidWYsCgkJCUZjVmFsdWVMaXN0CSp2LAoJCQlGY0NoYXI4CQkqZXNjYXBlKQp7CiAgICB3aGlsZSAodikKICAgIHsKCWlmICghRmNOYW1lVW5wYXJzZVZhbHVlIChidWYsIHYtPnZhbHVlLCBlc2NhcGUpKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKCh2ID0gdi0+bmV4dCkpCgkgICAgaWYgKCFGY05hbWVVbnBhcnNlU3RyaW5nIChidWYsIChGY0NoYXI4ICopICIsIiwgMCkpCgkJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgojZGVmaW5lIEZDX0VTQ0FQRV9GSVhFRCAgICAiXFwtOiwiCiNkZWZpbmUgRkNfRVNDQVBFX1ZBUklBQkxFICJcXD1fOiwiCgpGY0NoYXI4ICoKRmNOYW1lVW5wYXJzZSAoRmNQYXR0ZXJuICpwYXQpCnsKICAgIEZjU3RyQnVmCQkgICAgYnVmOwogICAgRmNDaGFyOAkJICAgIGJ1Zl9zdGF0aWNbODE5Ml07CiAgICBpbnQJCQkgICAgaTsKICAgIEZjUGF0dGVybkVsdAkgICAgKmU7CiAgICBjb25zdCBGY09iamVjdFR5cGVMaXN0ICAqbDsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZQkgICAgKm87CgogICAgRmNTdHJCdWZJbml0ICgmYnVmLCBidWZfc3RhdGljLCBzaXplb2YgKGJ1Zl9zdGF0aWMpKTsKICAgIGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwYXQsIEZDX0ZBTUlMWSk7CiAgICBpZiAoZSkKICAgIHsKCWlmICghRmNOYW1lVW5wYXJzZVZhbHVlTGlzdCAoJmJ1ZiwgZS0+dmFsdWVzLCAoRmNDaGFyOCAqKSBGQ19FU0NBUEVfRklYRUQpKQoJICAgIGdvdG8gYmFpbDA7CiAgICB9CiAgICBlID0gRmNQYXR0ZXJuRmluZEVsdCAocGF0LCBGQ19TSVpFKTsKICAgIGlmIChlKQogICAgewoJaWYgKCFGY05hbWVVbnBhcnNlU3RyaW5nICgmYnVmLCAoRmNDaGFyOCAqKSAiLSIsIDApKQoJICAgIGdvdG8gYmFpbDA7CglpZiAoIUZjTmFtZVVucGFyc2VWYWx1ZUxpc3QgKCZidWYsIGUtPnZhbHVlcywgKEZjQ2hhcjggKikgRkNfRVNDQVBFX0ZJWEVEKSkKCSAgICBnb3RvIGJhaWwwOwogICAgfQogICAgZm9yIChsID0gX0ZjT2JqZWN0VHlwZXM7IGw7IGwgPSBsLT5uZXh0KQogICAgewoJZm9yIChpID0gMDsgaSA8IGwtPm50eXBlczsgaSsrKQoJewoJICAgIG8gPSAmbC0+dHlwZXNbaV07CgkgICAgaWYgKCFzdHJjbXAgKG8tPm9iamVjdCwgRkNfRkFNSUxZKSB8fCAKCQkhc3RyY21wIChvLT5vYmplY3QsIEZDX1NJWkUpIHx8CgkJIXN0cmNtcCAoby0+b2JqZWN0LCBGQ19GSUxFKSkKCQljb250aW51ZTsKCSAgICAKCSAgICBlID0gRmNQYXR0ZXJuRmluZEVsdCAocGF0LCBvLT5vYmplY3QpOwoJICAgIGlmIChlKQoJICAgIHsKCQlpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKCZidWYsIChGY0NoYXI4ICopICI6IiwgMCkpCgkJICAgIGdvdG8gYmFpbDA7CgkJaWYgKCFGY05hbWVVbnBhcnNlU3RyaW5nICgmYnVmLCAoRmNDaGFyOCAqKSBvLT5vYmplY3QsIChGY0NoYXI4ICopIEZDX0VTQ0FQRV9WQVJJQUJMRSkpCgkJICAgIGdvdG8gYmFpbDA7CgkJaWYgKCFGY05hbWVVbnBhcnNlU3RyaW5nICgmYnVmLCAoRmNDaGFyOCAqKSAiPSIsIDApKQoJCSAgICBnb3RvIGJhaWwwOwoJCWlmICghRmNOYW1lVW5wYXJzZVZhbHVlTGlzdCAoJmJ1ZiwgZS0+dmFsdWVzLCAKCQkJCQkgICAgIChGY0NoYXI4ICopIEZDX0VTQ0FQRV9WQVJJQUJMRSkpCgkJICAgIGdvdG8gYmFpbDA7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIEZjU3RyQnVmRG9uZSAoJmJ1Zik7CmJhaWwwOgogICAgRmNTdHJCdWZEZXN0cm95ICgmYnVmKTsKICAgIHJldHVybiAwOwp9Cg==