LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY25hbWUuYyx2IDEuMTUgMjAwMi8wOS8yNiAwMDoxNzoyOCBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgImZjaW50LmgiCgpzdGF0aWMgY29uc3QgRmNPYmplY3RUeXBlIF9GY0Jhc2VPYmplY3RUeXBlc1tdID0gewogICAgeyBGQ19GQU1JTFksCUZjVHlwZVN0cmluZywgfSwKICAgIHsgRkNfU1RZTEUsCQlGY1R5cGVTdHJpbmcsIH0sCiAgICB7IEZDX1NMQU5ULAkJRmNUeXBlSW50ZWdlciwgfSwKICAgIHsgRkNfV0VJR0hULAlGY1R5cGVJbnRlZ2VyLCB9LAogICAgeyBGQ19TSVpFLAkJRmNUeXBlRG91YmxlLCB9LAogICAgeyBGQ19BU1BFQ1QsCUZjVHlwZURvdWJsZSwgfSwKICAgIHsgRkNfUElYRUxfU0laRSwJRmNUeXBlRG91YmxlLCB9LAogICAgeyBGQ19TUEFDSU5HLAlGY1R5cGVJbnRlZ2VyLCB9LAogICAgeyBGQ19GT1VORFJZLAlGY1R5cGVTdHJpbmcsIH0sCi8qICAgIHsgRkNfQ09SRSwJCUZjVHlwZUJvb2wsIH0sICovCiAgICB7IEZDX0FOVElBTElBUywJRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfSElOVElORywJRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfVkVSVElDQUxfTEFZT1VULCAgIEZjVHlwZUJvb2wsIH0sCiAgICB7IEZDX0FVVE9ISU5ULAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19HTE9CQUxfQURWQU5DRSwgICAgRmNUeXBlQm9vbCwgfSwKLyogICAgeyBGQ19YTEZELAkJRmNUeXBlU3RyaW5nLCB9LCAqLwogICAgeyBGQ19GSUxFLAkJRmNUeXBlU3RyaW5nLCB9LAogICAgeyBGQ19JTkRFWCwJCUZjVHlwZUludGVnZXIsIH0sCiAgICB7IEZDX1JBU1RFUklaRVIsCUZjVHlwZVN0cmluZywgfSwKICAgIHsgRkNfT1VUTElORSwJRmNUeXBlQm9vbCwgfSwKICAgIHsgRkNfU0NBTEFCTEUsCUZjVHlwZUJvb2wsIH0sCiAgICB7IEZDX0RQSSwJCUZjVHlwZURvdWJsZSB9LAogICAgeyBGQ19SR0JBLAkJRmNUeXBlSW50ZWdlciwgfSwKICAgIHsgRkNfU0NBTEUsCQlGY1R5cGVEb3VibGUsIH0sCi8qICAgIHsgRkNfUkVOREVSLAlGY1R5cGVCb29sLCB9LCovCiAgICB7IEZDX01JTlNQQUNFLAlGY1R5cGVCb29sLCB9LAogICAgeyBGQ19DSEFSX1dJRFRILAlGY1R5cGVJbnRlZ2VyIH0sCiAgICB7IEZDX0NIQVJfSEVJR0hULAlGY1R5cGVJbnRlZ2VyIH0sCiAgICB7IEZDX01BVFJJWCwJRmNUeXBlTWF0cml4IH0sCiAgICB7IEZDX0NIQVJTRVQsCUZjVHlwZUNoYXJTZXQgfSwKICAgIHsgRkNfTEFORywJCUZjVHlwZUxhbmdTZXQgfSwKICAgIHsgRkNfRk9OVFZFUlNJT04sCUZjVHlwZUludGVnZXIgfSwKfTsKCiNkZWZpbmUgTlVNX09CSkVDVF9UWVBFUyAgICAoc2l6ZW9mIF9GY0Jhc2VPYmplY3RUeXBlcyAvIHNpemVvZiBfRmNCYXNlT2JqZWN0VHlwZXNbMF0pCgp0eXBlZGVmIHN0cnVjdCBfRmNPYmplY3RUeXBlTGlzdCAgICBGY09iamVjdFR5cGVMaXN0OwoKc3RydWN0IF9GY09iamVjdFR5cGVMaXN0IHsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QgICpuZXh0OwogICAgY29uc3QgRmNPYmplY3RUeXBlCSAgICAqdHlwZXM7CiAgICBpbnQJCQkgICAgbnR5cGVzOwp9OwoKc3RhdGljIGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QgX0ZjQmFzZU9iamVjdFR5cGVzTGlzdCA9IHsKICAgIDAsCiAgICBfRmNCYXNlT2JqZWN0VHlwZXMsCiAgICBOVU1fT0JKRUNUX1RZUEVTCn07CgpzdGF0aWMgY29uc3QgRmNPYmplY3RUeXBlTGlzdAkqX0ZjT2JqZWN0VHlwZXMgPSAmX0ZjQmFzZU9iamVjdFR5cGVzTGlzdDsKCkZjQm9vbApGY05hbWVSZWdpc3Rlck9iamVjdFR5cGVzIChjb25zdCBGY09iamVjdFR5cGUgKnR5cGVzLCBpbnQgbnR5cGVzKQp7CiAgICBGY09iamVjdFR5cGVMaXN0CSpsOwoKICAgIGwgPSAoRmNPYmplY3RUeXBlTGlzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNPYmplY3RUeXBlTGlzdCkpOwogICAgaWYgKCFsKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fT0JKRUNUVFlQRSwgc2l6ZW9mIChGY09iamVjdFR5cGVMaXN0KSk7CiAgICBsLT50eXBlcyA9IHR5cGVzOwogICAgbC0+bnR5cGVzID0gbnR5cGVzOwogICAgbC0+bmV4dCA9IF9GY09iamVjdFR5cGVzOwogICAgX0ZjT2JqZWN0VHlwZXMgPSBsOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjTmFtZVVucmVnaXN0ZXJPYmplY3RUeXBlcyAoY29uc3QgRmNPYmplY3RUeXBlICp0eXBlcywgaW50IG50eXBlcykKewogICAgY29uc3QgRmNPYmplY3RUeXBlTGlzdAkqbCwgKipwcmV2OwoKICAgIGZvciAocHJldiA9ICZfRmNPYmplY3RUeXBlczsgCgkgKGwgPSAqcHJldik7IAoJIHByZXYgPSAoY29uc3QgRmNPYmplY3RUeXBlTGlzdCAqKikgJihsLT5uZXh0KSkKICAgIHsKCWlmIChsLT50eXBlcyA9PSB0eXBlcyAmJiBsLT5udHlwZXMgPT0gbnR5cGVzKQoJewoJICAgICpwcmV2ID0gbC0+bmV4dDsKCSAgICBGY01lbUZyZWUgKEZDX01FTV9PQkpFQ1RUWVBFLCBzaXplb2YgKEZjT2JqZWN0VHlwZUxpc3QpKTsKCSAgICBmcmVlICgodm9pZCAqKSBsKTsKCSAgICByZXR1cm4gRmNUcnVlOwoJfQogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCmNvbnN0IEZjT2JqZWN0VHlwZSAqCkZjTmFtZUdldE9iamVjdFR5cGUgKGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CQkJICAgIGk7CiAgICBjb25zdCBGY09iamVjdFR5cGVMaXN0ICAqbDsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZQkgICAgKnQ7CiAgICAKICAgIGZvciAobCA9IF9GY09iamVjdFR5cGVzOyBsOyBsID0gbC0+bmV4dCkKICAgIHsKCWZvciAoaSA9IDA7IGkgPCBsLT5udHlwZXM7IGkrKykKCXsKCSAgICB0ID0gJmwtPnR5cGVzW2ldOwoJICAgIGlmICghc3RyY21wIChvYmplY3QsIHQtPm9iamVjdCkpCgkJcmV0dXJuIHQ7Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGNvbnN0IEZjQ29uc3RhbnQgX0ZjQmFzZUNvbnN0YW50c1tdID0gewogICAgeyAoRmNDaGFyOCAqKSAibGlnaHQiLAkgICAgIndlaWdodCIsICAgRkNfV0VJR0hUX0xJR0hULCB9LAogICAgeyAoRmNDaGFyOCAqKSAibWVkaXVtIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9NRURJVU0sIH0sCiAgICB7IChGY0NoYXI4ICopICJkZW1pYm9sZCIsCSAgICAid2VpZ2h0IiwgICBGQ19XRUlHSFRfREVNSUJPTEQsIH0sCiAgICB7IChGY0NoYXI4ICopICJib2xkIiwJICAgICJ3ZWlnaHQiLCAgIEZDX1dFSUdIVF9CT0xELCB9LAogICAgeyAoRmNDaGFyOCAqKSAiYmxhY2siLAkgICAgIndlaWdodCIsICAgRkNfV0VJR0hUX0JMQUNLLCB9LAoKICAgIHsgKEZjQ2hhcjggKikgInJvbWFuIiwJICAgICJzbGFudCIsICAgIEZDX1NMQU5UX1JPTUFOLCB9LAogICAgeyAoRmNDaGFyOCAqKSAiaXRhbGljIiwJICAgICJzbGFudCIsICAgIEZDX1NMQU5UX0lUQUxJQywgfSwKICAgIHsgKEZjQ2hhcjggKikgIm9ibGlxdWUiLAkgICAgInNsYW50IiwgICAgRkNfU0xBTlRfT0JMSVFVRSwgfSwKCiAgICB7IChGY0NoYXI4ICopICJwcm9wb3J0aW9uYWwiLCAgICJzcGFjaW5nIiwgIEZDX1BST1BPUlRJT05BTCwgfSwKICAgIHsgKEZjQ2hhcjggKikgIm1vbm8iLAkgICAgInNwYWNpbmciLCAgRkNfTU9OTywgfSwKICAgIHsgKEZjQ2hhcjggKikgImNoYXJjZWxsIiwJICAgICJzcGFjaW5nIiwgIEZDX0NIQVJDRUxMLCB9LAoKICAgIHsgKEZjQ2hhcjggKikgInVua25vd24iLAkgICAgInJnYmEiLAkgICAgRkNfUkdCQV9VTktOT1dOIH0sCiAgICB7IChGY0NoYXI4ICopICJyZ2IiLAkgICAgInJnYmEiLAkgICAgRkNfUkdCQV9SR0IsIH0sCiAgICB7IChGY0NoYXI4ICopICJiZ3IiLAkgICAgInJnYmEiLAkgICAgRkNfUkdCQV9CR1IsIH0sCiAgICB7IChGY0NoYXI4ICopICJ2cmdiIiwJICAgICJyZ2JhIiwJICAgIEZDX1JHQkFfVlJHQiB9LAogICAgeyAoRmNDaGFyOCAqKSAidmJnciIsCSAgICAicmdiYSIsCSAgICBGQ19SR0JBX1ZCR1IgfSwKICAgIHsgKEZjQ2hhcjggKikgIm5vbmUiLAkgICAgInJnYmEiLAkgICAgRkNfUkdCQV9OT05FIH0sCn07CgojZGVmaW5lIE5VTV9GQ19DT05TVEFOVFMgICAoc2l6ZW9mIF9GY0Jhc2VDb25zdGFudHMvc2l6ZW9mIF9GY0Jhc2VDb25zdGFudHNbMF0pCgp0eXBlZGVmIHN0cnVjdCBfRmNDb25zdGFudExpc3QgRmNDb25zdGFudExpc3Q7CgpzdHJ1Y3QgX0ZjQ29uc3RhbnRMaXN0IHsKICAgIGNvbnN0IEZjQ29uc3RhbnRMaXN0ICAgICpuZXh0OwogICAgY29uc3QgRmNDb25zdGFudAkgICAgKmNvbnN0czsKICAgIGludAkJCSAgICBuY29uc3RzOwp9OwoKc3RhdGljIGNvbnN0IEZjQ29uc3RhbnRMaXN0IF9GY0Jhc2VDb25zdGFudExpc3QgPSB7CiAgICAwLAogICAgX0ZjQmFzZUNvbnN0YW50cywKICAgIE5VTV9GQ19DT05TVEFOVFMKfTsKCnN0YXRpYyBjb25zdCBGY0NvbnN0YW50TGlzdAkqX0ZjQ29uc3RhbnRzID0gJl9GY0Jhc2VDb25zdGFudExpc3Q7CgpGY0Jvb2wKRmNOYW1lUmVnaXN0ZXJDb25zdGFudHMgKGNvbnN0IEZjQ29uc3RhbnQgKmNvbnN0cywgaW50IG5jb25zdHMpCnsKICAgIEZjQ29uc3RhbnRMaXN0CSpsOwoKICAgIGwgPSAoRmNDb25zdGFudExpc3QgKikgbWFsbG9jIChzaXplb2YgKEZjQ29uc3RhbnRMaXN0KSk7CiAgICBpZiAoIWwpCglyZXR1cm4gRmNGYWxzZTsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9DT05TVEFOVCwgc2l6ZW9mIChGY0NvbnN0YW50TGlzdCkpOwogICAgbC0+Y29uc3RzID0gY29uc3RzOwogICAgbC0+bmNvbnN0cyA9IG5jb25zdHM7CiAgICBsLT5uZXh0ID0gX0ZjQ29uc3RhbnRzOwogICAgX0ZjQ29uc3RhbnRzID0gbDsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY05hbWVVbnJlZ2lzdGVyQ29uc3RhbnRzIChjb25zdCBGY0NvbnN0YW50ICpjb25zdHMsIGludCBuY29uc3RzKQp7CiAgICBjb25zdCBGY0NvbnN0YW50TGlzdAkqbCwgKipwcmV2OwoKICAgIGZvciAocHJldiA9ICZfRmNDb25zdGFudHM7IAoJIChsID0gKnByZXYpOyAKCSBwcmV2ID0gKGNvbnN0IEZjQ29uc3RhbnRMaXN0ICoqKSAmKGwtPm5leHQpKQogICAgewoJaWYgKGwtPmNvbnN0cyA9PSBjb25zdHMgJiYgbC0+bmNvbnN0cyA9PSBuY29uc3RzKQoJewoJICAgICpwcmV2ID0gbC0+bmV4dDsKCSAgICBGY01lbUZyZWUgKEZDX01FTV9DT05TVEFOVCwgc2l6ZW9mIChGY0NvbnN0YW50TGlzdCkpOwoJICAgIGZyZWUgKCh2b2lkICopIGwpOwoJICAgIHJldHVybiBGY1RydWU7Cgl9CiAgICB9CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKY29uc3QgRmNDb25zdGFudCAqCkZjTmFtZUdldENvbnN0YW50IChGY0NoYXI4ICpzdHJpbmcpCnsKICAgIGNvbnN0IEZjQ29uc3RhbnRMaXN0ICAgICpsOwogICAgaW50CQkJICAgIGk7CiAgICAKICAgIGZvciAobCA9IF9GY0NvbnN0YW50czsgbDsgbCA9IGwtPm5leHQpCiAgICB7Cglmb3IgKGkgPSAwOyBpIDwgbC0+bmNvbnN0czsgaSsrKQoJICAgIGlmICghRmNTdHJDbXBJZ25vcmVDYXNlIChzdHJpbmcsIGwtPmNvbnN0c1tpXS5uYW1lKSkKCQlyZXR1cm4gJmwtPmNvbnN0c1tpXTsKICAgIH0KICAgIHJldHVybiAwOwp9CgpGY0Jvb2wKRmNOYW1lQ29uc3RhbnQgKEZjQ2hhcjggKnN0cmluZywgaW50ICpyZXN1bHQpCnsKICAgIGNvbnN0IEZjQ29uc3RhbnQJKmM7CgogICAgaWYgKChjID0gRmNOYW1lR2V0Q29uc3RhbnQoc3RyaW5nKSkpCiAgICB7CgkqcmVzdWx0ID0gYy0+dmFsdWU7CglyZXR1cm4gRmNUcnVlOwogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY05hbWVCb29sIChGY0NoYXI4ICp2LCBGY0Jvb2wgKnJlc3VsdCkKewogICAgY2hhciAgICBjMCwgYzE7CgogICAgYzAgPSAqdjsKICAgIGlmIChpc3VwcGVyIChjMCkpCgljMCA9IHRvbG93ZXIgKGMwKTsKICAgIGlmIChjMCA9PSAndCcgfHwgYzAgPT0gJ3knIHx8IGMwID09ICcxJykKICAgIHsKCSpyZXN1bHQgPSBGY1RydWU7CglyZXR1cm4gRmNUcnVlOwogICAgfQogICAgaWYgKGMwID09ICdmJyB8fCBjMCA9PSAnbicgfHwgYzAgPT0gJzAnKQogICAgewoJKnJlc3VsdCA9IEZjRmFsc2U7CglyZXR1cm4gRmNUcnVlOwogICAgfQogICAgaWYgKGMwID09ICdvJykKICAgIHsKCWMxID0gdlsxXTsKCWlmIChpc3VwcGVyIChjMSkpCgkgICAgYzEgPSB0b2xvd2VyIChjMSk7CglpZiAoYzEgPT0gJ24nKQoJewoJICAgICpyZXN1bHQgPSBGY1RydWU7CgkgICAgcmV0dXJuIEZjVHJ1ZTsKCX0KCWlmIChjMSA9PSAnZicpCgl7CgkgICAgKnJlc3VsdCA9IEZjRmFsc2U7CgkgICAgcmV0dXJuIEZjVHJ1ZTsKCX0KICAgIH0KICAgIHJldHVybiBGY0ZhbHNlOwp9CgpzdGF0aWMgRmNWYWx1ZQpGY05hbWVDb252ZXJ0IChGY1R5cGUgdHlwZSwgRmNDaGFyOCAqc3RyaW5nLCBGY01hdHJpeCAqbSkKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IHR5cGU7CiAgICBzd2l0Y2ggKHYudHlwZSkgewogICAgY2FzZSBGY1R5cGVJbnRlZ2VyOgoJaWYgKCFGY05hbWVDb25zdGFudCAoc3RyaW5nLCAmdi51LmkpKQoJICAgIHYudS5pID0gYXRvaSAoKGNoYXIgKikgc3RyaW5nKTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVTdHJpbmc6Cgl2LnUucyA9IHN0cmluZzsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVCb29sOgoJaWYgKCFGY05hbWVCb29sIChzdHJpbmcsICZ2LnUuYikpCgkgICAgdi51LmIgPSBGY0ZhbHNlOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCXYudS5kID0gc3RydG9kICgoY2hhciAqKSBzdHJpbmcsIDApOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZU1hdHJpeDoKCXYudS5tID0gbTsKCXNzY2FuZiAoKGNoYXIgKikgc3RyaW5nLCAiJWxnICVsZyAlbGcgJWxnIiwgJm0tPnh4LCAmbS0+eHksICZtLT55eCwgJm0tPnl5KTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJdi51LmMgPSBGY05hbWVQYXJzZUNoYXJTZXQgKHN0cmluZyk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTGFuZ1NldDoKCXYudS5sID0gRmNOYW1lUGFyc2VMYW5nU2V0IChzdHJpbmcpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJYnJlYWs7CiAgICB9CiAgICByZXR1cm4gdjsKfQoKc3RhdGljIGNvbnN0IEZjQ2hhcjggKgpGY05hbWVGaW5kTmV4dCAoY29uc3QgRmNDaGFyOCAqY3VyLCBjb25zdCBjaGFyICpkZWxpbSwgRmNDaGFyOCAqc2F2ZSwgRmNDaGFyOCAqbGFzdCkKewogICAgRmNDaGFyOCAgICBjOwogICAgCiAgICB3aGlsZSAoKGMgPSAqY3VyKSkKICAgIHsKCWlmIChjID09ICdcXCcpCgl7CgkgICAgKytjdXI7CgkgICAgaWYgKCEoYyA9ICpjdXIpKQoJCWJyZWFrOwoJfQoJZWxzZSBpZiAoc3RyY2hyIChkZWxpbSwgYykpCgkgICAgYnJlYWs7CgkrK2N1cjsKCSpzYXZlKysgPSBjOwogICAgfQogICAgKnNhdmUgPSAwOwogICAgKmxhc3QgPSAqY3VyOwogICAgaWYgKCpjdXIpCgljdXIrKzsKICAgIHJldHVybiBjdXI7Cn0KCkZjUGF0dGVybiAqCkZjTmFtZVBhcnNlIChjb25zdCBGY0NoYXI4ICpuYW1lKQp7CiAgICBGY0NoYXI4CQkqc2F2ZTsKICAgIEZjUGF0dGVybgkJKnBhdDsKICAgIGRvdWJsZQkJZDsKICAgIEZjQ2hhcjgJCSplOwogICAgRmNDaGFyOAkJZGVsaW07CiAgICBGY1ZhbHVlCQl2OwogICAgRmNNYXRyaXgJCW07CiAgICBjb25zdCBGY09iamVjdFR5cGUJKnQ7CiAgICBjb25zdCBGY0NvbnN0YW50CSpjOwoKICAgIC8qIGZyZWVkIGJlbG93ICovCiAgICBzYXZlID0gbWFsbG9jIChzdHJsZW4gKChjaGFyICopIG5hbWUpICsgMSk7CiAgICBpZiAoIXNhdmUpCglnb3RvIGJhaWwwOwogICAgcGF0ID0gRmNQYXR0ZXJuQ3JlYXRlICgpOwogICAgaWYgKCFwYXQpCglnb3RvIGJhaWwxOwoKICAgIGZvciAoOzspCiAgICB7CgluYW1lID0gRmNOYW1lRmluZE5leHQgKG5hbWUsICItLDoiLCBzYXZlLCAmZGVsaW0pOwoJaWYgKHNhdmVbMF0pCgl7CgkgICAgaWYgKCFGY1BhdHRlcm5BZGRTdHJpbmcgKHBhdCwgRkNfRkFNSUxZLCBzYXZlKSkKCQlnb3RvIGJhaWwyOwoJfQoJaWYgKGRlbGltICE9ICcsJykKCSAgICBicmVhazsKICAgIH0KICAgIGlmIChkZWxpbSA9PSAnLScpCiAgICB7Cglmb3IgKDs7KQoJewoJICAgIG5hbWUgPSBGY05hbWVGaW5kTmV4dCAobmFtZSwgIi0sOiIsIHNhdmUsICZkZWxpbSk7CgkgICAgZCA9IHN0cnRvZCAoKGNoYXIgKikgc2F2ZSwgKGNoYXIgKiopICZlKTsKCSAgICBpZiAoZSAhPSBzYXZlKQoJICAgIHsKCQlpZiAoIUZjUGF0dGVybkFkZERvdWJsZSAocGF0LCBGQ19TSVpFLCBkKSkKCQkgICAgZ290byBiYWlsMjsKCSAgICB9CgkgICAgaWYgKGRlbGltICE9ICcsJykKCQlicmVhazsKCX0KICAgIH0KICAgIHdoaWxlIChkZWxpbSA9PSAnOicpCiAgICB7CgluYW1lID0gRmNOYW1lRmluZE5leHQgKG5hbWUsICI9XzoiLCBzYXZlLCAmZGVsaW0pOwoJaWYgKHNhdmVbMF0pCgl7CgkgICAgaWYgKGRlbGltID09ICc9JyB8fCBkZWxpbSA9PSAnXycpCgkgICAgewoJCXQgPSBGY05hbWVHZXRPYmplY3RUeXBlICgoY2hhciAqKSBzYXZlKTsKCQlmb3IgKDs7KQoJCXsKCQkgICAgbmFtZSA9IEZjTmFtZUZpbmROZXh0IChuYW1lLCAiOiwiLCBzYXZlLCAmZGVsaW0pOwoJCSAgICBpZiAodCkKCQkgICAgewoJCQl2ID0gRmNOYW1lQ29udmVydCAodC0+dHlwZSwgc2F2ZSwgJm0pOwoJCQlpZiAoIUZjUGF0dGVybkFkZCAocGF0LCB0LT5vYmplY3QsIHYsIEZjVHJ1ZSkpCgkJCXsKCQkJICAgIHN3aXRjaCAodi50eXBlKSB7CgkJCSAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6CgkJCQlGY0NoYXJTZXREZXN0cm95ICgoRmNDaGFyU2V0ICopIHYudS5jKTsKCQkJCWJyZWFrOwoJCQkgICAgY2FzZSBGY1R5cGVMYW5nU2V0OgoJCQkJRmNMYW5nU2V0RGVzdHJveSAoKEZjTGFuZ1NldCAqKSB2LnUubCk7CgkJCQlicmVhazsKCQkJICAgIGRlZmF1bHQ6CgkJCQlicmVhazsKCQkJICAgIH0KCQkJICAgIGdvdG8gYmFpbDI7CgkJCX0KCQkJc3dpdGNoICh2LnR5cGUpIHsKCQkJY2FzZSBGY1R5cGVDaGFyU2V0OgoJCQkgICAgRmNDaGFyU2V0RGVzdHJveSAoKEZjQ2hhclNldCAqKSB2LnUuYyk7CgkJCSAgICBicmVhazsKCQkJY2FzZSBGY1R5cGVMYW5nU2V0OgoJCQkgICAgRmNMYW5nU2V0RGVzdHJveSAoKEZjTGFuZ1NldCAqKSB2LnUubCk7CgkJCSAgICBicmVhazsKCQkJZGVmYXVsdDoKCQkJICAgIGJyZWFrOwoJCQl9CgkJICAgIH0KCQkgICAgaWYgKGRlbGltICE9ICcsJykKCQkJYnJlYWs7CgkJfQoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCWlmICgoYyA9IEZjTmFtZUdldENvbnN0YW50IChzYXZlKSkpCgkJewoJCSAgICBpZiAoIUZjUGF0dGVybkFkZEludGVnZXIgKHBhdCwgYy0+b2JqZWN0LCBjLT52YWx1ZSkpCgkJCWdvdG8gYmFpbDI7CgkJfQoJICAgIH0KCX0KICAgIH0KCiAgICBmcmVlIChzYXZlKTsKICAgIHJldHVybiBwYXQ7CgpiYWlsMjoKICAgIEZjUGF0dGVybkRlc3Ryb3kgKHBhdCk7CmJhaWwxOgogICAgZnJlZSAoc2F2ZSk7CmJhaWwwOgogICAgcmV0dXJuIDA7Cn0Kc3RhdGljIEZjQm9vbApGY05hbWVVbnBhcnNlU3RyaW5nIChGY1N0ckJ1ZgkgICAgKmJ1ZiwgCgkJICAgICBjb25zdCBGY0NoYXI4ICAqc3RyaW5nLAoJCSAgICAgY29uc3QgRmNDaGFyOCAgKmVzY2FwZSkKewogICAgRmNDaGFyOCBjOwogICAgd2hpbGUgKChjID0gKnN0cmluZysrKSkKICAgIHsKCWlmIChlc2NhcGUgJiYgc3RyY2hyICgoY2hhciAqKSBlc2NhcGUsIChjaGFyKSBjKSkKCXsKCSAgICBpZiAoIUZjU3RyQnVmQ2hhciAoYnVmLCBlc2NhcGVbMF0pKQoJCXJldHVybiBGY0ZhbHNlOwoJfQoJaWYgKCFGY1N0ckJ1ZkNoYXIgKGJ1ZiwgYykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjTmFtZVVucGFyc2VWYWx1ZSAoRmNTdHJCdWYJKmJ1ZiwKCQkgICAgRmNWYWx1ZQl2LAoJCSAgICBGY0NoYXI4CSplc2NhcGUpCnsKICAgIEZjQ2hhcjgJdGVtcFsxMDI0XTsKICAgIAogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlVm9pZDoKCXJldHVybiBGY1RydWU7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6CglzcHJpbnRmICgoY2hhciAqKSB0ZW1wLCAiJWQiLCB2LnUuaSk7CglyZXR1cm4gRmNOYW1lVW5wYXJzZVN0cmluZyAoYnVmLCB0ZW1wLCAwKTsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJc3ByaW50ZiAoKGNoYXIgKikgdGVtcCwgIiVnIiwgdi51LmQpOwoJcmV0dXJuIEZjTmFtZVVucGFyc2VTdHJpbmcgKGJ1ZiwgdGVtcCwgMCk7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCXJldHVybiBGY05hbWVVbnBhcnNlU3RyaW5nIChidWYsIHYudS5zLCBlc2NhcGUpOwogICAgY2FzZSBGY1R5cGVCb29sOgoJcmV0dXJuIEZjTmFtZVVucGFyc2VTdHJpbmcgKGJ1Ziwgdi51LmIgPyAoRmNDaGFyOCAqKSAiVHJ1ZSIgOiAoRmNDaGFyOCAqKSAiRmFsc2UiLCAwKTsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJc3ByaW50ZiAoKGNoYXIgKikgdGVtcCwgIiVnICVnICVnICVnIiwgCgkJIHYudS5tLT54eCwgdi51Lm0tPnh5LCB2LnUubS0+eXgsIHYudS5tLT55eSk7CglyZXR1cm4gRmNOYW1lVW5wYXJzZVN0cmluZyAoYnVmLCB0ZW1wLCAwKTsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXJldHVybiBGY05hbWVVbnBhcnNlQ2hhclNldCAoYnVmLCB2LnUuYyk7CiAgICBjYXNlIEZjVHlwZUxhbmdTZXQ6CglyZXR1cm4gRmNOYW1lVW5wYXJzZUxhbmdTZXQgKGJ1Ziwgdi51LmwpOwogICAgY2FzZSBGY1R5cGVGVEZhY2U6CglyZXR1cm4gRmNUcnVlOwogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNOYW1lVW5wYXJzZVZhbHVlTGlzdCAoRmNTdHJCdWYJKmJ1ZiwKCQkJRmNWYWx1ZUxpc3QJKnYsCgkJCUZjQ2hhcjgJCSplc2NhcGUpCnsKICAgIHdoaWxlICh2KQogICAgewoJaWYgKCFGY05hbWVVbnBhcnNlVmFsdWUgKGJ1Ziwgdi0+dmFsdWUsIGVzY2FwZSkpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglpZiAoKHYgPSB2LT5uZXh0KSkKCSAgICBpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKGJ1ZiwgKEZjQ2hhcjggKikgIiwiLCAwKSkKCQlyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCiNkZWZpbmUgRkNfRVNDQVBFX0ZJWEVEICAgICJcXC06LCIKI2RlZmluZSBGQ19FU0NBUEVfVkFSSUFCTEUgIlxcPV86LCIKCkZjQ2hhcjggKgpGY05hbWVVbnBhcnNlIChGY1BhdHRlcm4gKnBhdCkKewogICAgRmNTdHJCdWYJCSAgICBidWY7CiAgICBGY0NoYXI4CQkgICAgYnVmX3N0YXRpY1s4MTkyXTsKICAgIGludAkJCSAgICBpOwogICAgRmNQYXR0ZXJuRWx0CSAgICAqZTsKICAgIGNvbnN0IEZjT2JqZWN0VHlwZUxpc3QgICpsOwogICAgY29uc3QgRmNPYmplY3RUeXBlCSAgICAqbzsKCiAgICBGY1N0ckJ1ZkluaXQgKCZidWYsIGJ1Zl9zdGF0aWMsIHNpemVvZiAoYnVmX3N0YXRpYykpOwogICAgZSA9IEZjUGF0dGVybkZpbmRFbHQgKHBhdCwgRkNfRkFNSUxZKTsKICAgIGlmIChlKQogICAgewoJaWYgKCFGY05hbWVVbnBhcnNlVmFsdWVMaXN0ICgmYnVmLCBlLT52YWx1ZXMsIChGY0NoYXI4ICopIEZDX0VTQ0FQRV9GSVhFRCkpCgkgICAgZ290byBiYWlsMDsKICAgIH0KICAgIGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwYXQsIEZDX1NJWkUpOwogICAgaWYgKGUpCiAgICB7CglpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKCZidWYsIChGY0NoYXI4ICopICItIiwgMCkpCgkgICAgZ290byBiYWlsMDsKCWlmICghRmNOYW1lVW5wYXJzZVZhbHVlTGlzdCAoJmJ1ZiwgZS0+dmFsdWVzLCAoRmNDaGFyOCAqKSBGQ19FU0NBUEVfRklYRUQpKQoJICAgIGdvdG8gYmFpbDA7CiAgICB9CiAgICBmb3IgKGwgPSBfRmNPYmplY3RUeXBlczsgbDsgbCA9IGwtPm5leHQpCiAgICB7Cglmb3IgKGkgPSAwOyBpIDwgbC0+bnR5cGVzOyBpKyspCgl7CgkgICAgbyA9ICZsLT50eXBlc1tpXTsKCSAgICBpZiAoIXN0cmNtcCAoby0+b2JqZWN0LCBGQ19GQU1JTFkpIHx8IAoJCSFzdHJjbXAgKG8tPm9iamVjdCwgRkNfU0laRSkgfHwKCQkhc3RyY21wIChvLT5vYmplY3QsIEZDX0ZJTEUpKQoJCWNvbnRpbnVlOwoJICAgIAoJICAgIGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwYXQsIG8tPm9iamVjdCk7CgkgICAgaWYgKGUpCgkgICAgewoJCWlmICghRmNOYW1lVW5wYXJzZVN0cmluZyAoJmJ1ZiwgKEZjQ2hhcjggKikgIjoiLCAwKSkKCQkgICAgZ290byBiYWlsMDsKCQlpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKCZidWYsIChGY0NoYXI4ICopIG8tPm9iamVjdCwgKEZjQ2hhcjggKikgRkNfRVNDQVBFX1ZBUklBQkxFKSkKCQkgICAgZ290byBiYWlsMDsKCQlpZiAoIUZjTmFtZVVucGFyc2VTdHJpbmcgKCZidWYsIChGY0NoYXI4ICopICI9IiwgMCkpCgkJICAgIGdvdG8gYmFpbDA7CgkJaWYgKCFGY05hbWVVbnBhcnNlVmFsdWVMaXN0ICgmYnVmLCBlLT52YWx1ZXMsIAoJCQkJCSAgICAgKEZjQ2hhcjggKikgRkNfRVNDQVBFX1ZBUklBQkxFKSkKCQkgICAgZ290byBiYWlsMDsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gRmNTdHJCdWZEb25lICgmYnVmKTsKYmFpbDA6CiAgICBGY1N0ckJ1ZkRlc3Ryb3kgKCZidWYpOwogICAgcmV0dXJuIDA7Cn0K