LyoKICogbXNpZXhlYy5leGUgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDQgVmluY2VudCBC6XJvbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8d2luZG93cy5oPgojaW5jbHVkZSA8bXNpLmg+CiNpbmNsdWRlIDxvYmpiYXNlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgIm1zaWV4ZWMuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChtc2lleGVjKTsKCnN0YXRpYyBjb25zdCBjaGFyIFVzYWdlU3RyW10gPQoiVXNhZ2U6XG4iCiIgIEluc3RhbGwgYSBwcm9kdWN0OlxuIgoiICAgIG1zaWV4ZWMge3BhY2thZ2V8cHJvZHVjdGNvZGV9IFtwcm9wZXJ0eV1cbiIKIiAgICBtc2lleGVjIC9pIHtwYWNrYWdlfHByb2R1Y3Rjb2RlfSBbcHJvcGVydHldXG4iCiIgICAgbXNpZXhlYyAvYSBwYWNrYWdlIFtwcm9wZXJ0eV1cbiIKIiAgUmVwYWlyIGFuIGluc3RhbGxhdGlvbjpcbiIKIiAgICBtc2lleGVjIC9mW3B8b3xlfGR8Y3xhfHV8bXxzfHZdIHtwYWNrYWdlfHByb2R1Y3Rjb2RlfVxuIgoiICBVbmluc3RhbGwgYSBwcm9kdWN0OlxuIgoiICAgIG1zaWV4ZWMgL3gge3BhY2thZ2V8cHJvZHVjdGNvZGV9IFtwcm9wZXJ0eV1cbiIKIiAgQWR2ZXJ0aXNlIGEgcHJvZHVjdDpcbiIKIiAgICBtc2lleGVjIC9qW3V8bV0gcGFja2FnZSBbL3QgdHJhbnNmb3JtXSBbL2cgbGFuZ3VhZ2VpZF1cbiIKIiAgICBtc2lleGVjIHt1fG19IHBhY2thZ2UgWy90IHRyYW5zZm9ybV0gWy9nIGxhbmd1YWdlaWRdXG4iCiIgIEFwcGx5IGEgcGF0Y2g6XG4iCiIgICAgbXNpZXhlYyAvcCBwYXRjaHBhY2thZ2UgW3Byb3BlcnR5XVxuIgoiICAgIG1zaWV4ZWMgL3AgcGF0Y2hwYWNrYWdlIC9hIHBhY2thZ2UgW3Byb3BlcnR5XVxuIgoiICBNb2RpZmllcnMgZm9yIGFib3ZlIG9wZXJhdGlvbnM6XG4iCiIgICAgbXNpZXhlYyAvbFsqXVtpfHd8ZXxhfHJ8dXxjfG18b3xwfHZ8XVsrfCFdIGxvZ2ZpbGVcbiIKIiAgICBtc2lleGVjIC9xe3xufGJ8cnxmfG4rfGIrfGItfVxuIgoiICBSZWdpc3RlciBhIG1vZHVsZTpcbiIKIiAgICBtc2lleGVjIC95IG1vZHVsZVxuIgoiICBVbnJlZ2lzdGVyIGEgbW9kdWxlOlxuIgoiICAgIG1zaWV4ZWMgL3ogbW9kdWxlXG4iCiIgIERpc3BsYXkgdXNhZ2UgYW5kIGNvcHlyaWdodDpcbiIKIiAgICBtc2lleGVjIHsvaHwvP31cbiIKIk5PVEU6IFByb2R1Y3QgY29kZSBvbiBjb21tYW5kbGluZSB1bmltcGxlbWVudGVkIGFzIG9mIHlldFxuIgoiXG4iCiJDb3B5cmlnaHQgMjAwNCBWaW5jZW50IELpcm9uXG4iOwoKc3RhdGljIGNvbnN0IGNoYXIgQWN0aW9uQWRtaW5bXSA9ICJBQ1RJT049QURNSU4gIjsKc3RhdGljIGNvbnN0IGNoYXIgUmVtb3ZlQWxsW10gPSAiUkVNT1ZFPUFMTCAiOwoKc3RhdGljIHZvaWQgU2hvd1VzYWdlKGludCBFeGl0Q29kZSkKewoJcHJpbnRmKFVzYWdlU3RyKTsKCUV4aXRQcm9jZXNzKEV4aXRDb2RlKTsKfQoKc3RhdGljIEJPT0wgR2V0UHJvZHVjdENvZGUoTFBDU1RSIHN0ciwgTFBDU1RSICpQYWNrYWdlTmFtZSwgTFBHVUlEICpQcm9kdWN0Q29kZSkKewoJQk9PTCByZXQgPSBGQUxTRTsKCWludCBsZW4gPSAwOwoJTFBXU1RSIHdzdHIgPSBOVUxMOwoKCWlmKHN0cmxlbihzdHIpID09IDM4KQoJewoJCWxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzdHIsIC0xLCB3c3RyLCAwKTsKCQl3c3RyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIChsZW4rMSkqc2l6ZW9mKFdDSEFSKSk7CgkJcmV0ID0gKENMU0lERnJvbVN0cmluZyh3c3RyLCAqUHJvZHVjdENvZGUpID09IE5PRVJST1IpOwoJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHdzdHIpOwoJCXdzdHIgPSBOVUxMOwoJfQoKCWlmKCFyZXQpCgl7CgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKlByb2R1Y3RDb2RlKTsKCQkqUHJvZHVjdENvZGUgPSBOVUxMOwoJCSpQYWNrYWdlTmFtZSA9IHN0cjsKCX0KCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgVk9JRCBTdHJpbmdMaXN0QXBwZW5kKExQU1RSICpTdHJpbmdMaXN0LCBMUENTVFIgU3RyaW5nQXBwZW5kKQp7CglMUFNUUiBUZW1wU3RyID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKlN0cmluZ0xpc3QsIEhlYXBTaXplKEdldFByb2Nlc3NIZWFwKCksIDAsICpTdHJpbmdMaXN0KStzdHJsZW4oU3RyaW5nQXBwZW5kKSk7CglpZighVGVtcFN0cikKCXsKCQlXSU5FX0VSUigiT3V0IG9mIG1lbW9yeSFcbiIpOwoJCUV4aXRQcm9jZXNzKDEpOwoJfQoJKlN0cmluZ0xpc3QgPSBUZW1wU3RyOwoJc3RyY2F0KCpTdHJpbmdMaXN0LCBTdHJpbmdBcHBlbmQpOwp9CgpzdGF0aWMgVk9JRCBTdHJpbmdDb21wYXJlUmVtb3ZlTGFzdChMUFNUUiBTdHJpbmcsIENIQVIgY2hhcmFjdGVyKQp7CglpbnQgbGVuID0gc3RybGVuKFN0cmluZyk7CglpZihsZW4gJiYgU3RyaW5nW2xlbi0xXSA9PSBjaGFyYWN0ZXIpIFN0cmluZ1tsZW4tMV0gPSAwOwp9CgpzdGF0aWMgVk9JRCAqTG9hZFByb2MoTFBDU1RSIERsbE5hbWUsIExQQ1NUUiBQcm9jTmFtZSwgSE1PRFVMRSogRGxsSGFuZGxlKQp7CglWT0lEKiAoKnByb2MpKHZvaWQpOwoKCSpEbGxIYW5kbGUgPSBMb2FkTGlicmFyeUV4QShEbGxOYW1lLCBOVUxMLCBMT0FEX1dJVEhfQUxURVJFRF9TRUFSQ0hfUEFUSCk7CglpZighKkRsbEhhbmRsZSkKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb2FkIGRsbCAlc1xuIiwgRGxsTmFtZSk7CgkJRXhpdFByb2Nlc3MoMSk7Cgl9Cglwcm9jID0gKFZPSUQgKikgR2V0UHJvY0FkZHJlc3MoKkRsbEhhbmRsZSwgUHJvY05hbWUpOwoJaWYoIXByb2MpCgl7CgkJZnByaW50ZihzdGRlcnIsICJEbGwgJXMgZG9lcyBub3QgaW1wbGVtZW50IGZ1bmN0aW9uICVzXG4iLCBEbGxOYW1lLCBQcm9jTmFtZSk7CgkJRnJlZUxpYnJhcnkoKkRsbEhhbmRsZSk7CgkJRXhpdFByb2Nlc3MoMSk7Cgl9CgoJcmV0dXJuIHByb2M7Cn0KCnN0YXRpYyB2b2lkIERsbFJlZ2lzdGVyU2VydmVyKExQQ1NUUiBEbGxOYW1lKQp7CglIUkVTVUxUIGhyOwoJRExMUkVHSVNURVJTRVJWRVIgcGZEbGxSZWdpc3RlclNlcnZlciA9IE5VTEw7CglITU9EVUxFIERsbEhhbmRsZSA9IE5VTEw7CgoJcGZEbGxSZWdpc3RlclNlcnZlciA9IExvYWRQcm9jKERsbE5hbWUsICJEbGxSZWdpc3RlclNlcnZlciIsICZEbGxIYW5kbGUpOwoKCWhyID0gcGZEbGxSZWdpc3RlclNlcnZlcigpOwoJaWYoRkFJTEVEKGhyKSkKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCB0byByZWdpc3RlciBkbGwgJXNcbiIsIERsbE5hbWUpOwoJCUV4aXRQcm9jZXNzKDEpOwoJfQoJcHJpbnRmKCJTdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCBkbGwgJXNcbiIsIERsbE5hbWUpOwoJaWYoRGxsSGFuZGxlKQoJCUZyZWVMaWJyYXJ5KERsbEhhbmRsZSk7Cn0KCnN0YXRpYyB2b2lkIERsbFVucmVnaXN0ZXJTZXJ2ZXIoTFBDU1RSIERsbE5hbWUpCnsKCUhSRVNVTFQgaHI7CglETExVTlJFR0lTVEVSU0VSVkVSIHBmRGxsVW5yZWdpc3RlclNlcnZlciA9IE5VTEw7CglITU9EVUxFIERsbEhhbmRsZSA9IE5VTEw7CgoJcGZEbGxVbnJlZ2lzdGVyU2VydmVyID0gTG9hZFByb2MoRGxsTmFtZSwgIkRsbFVucmVnaXN0ZXJTZXJ2ZXIiLCAmRGxsSGFuZGxlKTsKCglociA9IHBmRGxsVW5yZWdpc3RlclNlcnZlcigpOwoJaWYoRkFJTEVEKGhyKSkKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCB0byB1bnJlZ2lzdGVyIGRsbCAlc1xuIiwgRGxsTmFtZSk7CgkJRXhpdFByb2Nlc3MoMSk7Cgl9CglwcmludGYoIlN1Y2Nlc3NmdWxseSB1bnJlZ2lzdGVyZWQgZGxsICVzXG4iLCBEbGxOYW1lKTsKCWlmKERsbEhhbmRsZSkKCQlGcmVlTGlicmFyeShEbGxIYW5kbGUpOwp9CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKQp7CglpbnQgaTsKCUJPT0wgRnVuY3Rpb25JbnN0YWxsID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uSW5zdGFsbEFkbWluID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uUmVwYWlyID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uQWR2ZXJ0aXNlID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uUGF0Y2ggPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25EbGxSZWdpc3RlclNlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvbkRsbFVucmVnaXN0ZXJTZXJ2ZXIgPSBGQUxTRTsKCglCT09MIEdvdFByb2R1Y3RDb2RlID0gRkFMU0U7CglMUENTVFIgUGFja2FnZU5hbWUgPSBOVUxMOwoJTFBHVUlEIFByb2R1Y3RDb2RlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihHVUlEKSk7CglMUFNUUiBQcm9wZXJ0aWVzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIDEpOwoKCURXT1JEIFJlcGFpck1vZGUgPSAwOwoKCURXT1JEIEFkdmVydGlzZU1vZGUgPSAwOwoJTFBTVFIgVHJhbnNmb3JtcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCAxKTsKCUxBTkdJRCBMYW5ndWFnZSA9IDA7CgoJRFdPUkQgTG9nTW9kZSA9IDA7CglMUFNUUiBMb2dGaWxlTmFtZSA9IE5VTEw7CglEV09SRCBMb2dBdHRyaWJ1dGVzID0gMDsKCglMUFNUUiBQYXRjaEZpbGVOYW1lID0gTlVMTDsKCUlOU1RBTExUWVBFIEluc3RhbGxUeXBlID0gSU5TVEFMTFRZUEVfREVGQVVMVDsKCglJTlNUQUxMVUlMRVZFTCBJbnN0YWxsVUlMZXZlbCA9IDAsIHJldEluc3RhbGxVSUxldmVsOwoKCUxQU1RSIERsbE5hbWUgPSBOVUxMOwoKCVByb3BlcnRpZXNbMF0gPSAwOwoJVHJhbnNmb3Jtc1swXSA9IDA7CgoJZm9yKGkgPSAxOyBpIDwgYXJnYzsgaSsrKQoJewoJCVdJTkVfVFJBQ0UoImFyZ3ZbJWRdID0gJXNcbiIsIGksIGFyZ3ZbaV0pOwoKCQlpZighc3RybmNhc2VjbXAoYXJndltpXSwgIi9pIiwgMikpCgkJewoJCQljaGFyICphcmd2aSA9IGFyZ3ZbaV07CgkJCUZ1bmN0aW9uSW5zdGFsbCA9IFRSVUU7CgkJCWlmKHN0cmxlbihhcmd2aSkgPiAyKQoJCQkJYXJndmkgKz0gMjsKCQkJZWxzZSB7CgkJCQlpKys7CgkJCQlpZihpID49IGFyZ2MpCgkJCQkJU2hvd1VzYWdlKDEpOwoJCQkJV0lORV9UUkFDRSgiYXJndlslZF0gPSAlc1xuIiwgaSwgYXJndltpXSk7CgkJCX0KCQkJR290UHJvZHVjdENvZGUgPSBHZXRQcm9kdWN0Q29kZShhcmd2aSwgJlBhY2thZ2VOYW1lLCAmUHJvZHVjdENvZGUpOwoJCX0KCQllbHNlIGlmKCFzdHJjYXNlY21wKGFyZ3ZbaV0sICIvYSIpKQoJCXsKCQkJRnVuY3Rpb25JbnN0YWxsID0gVFJVRTsKCQkJRnVuY3Rpb25JbnN0YWxsQWRtaW4gPSBUUlVFOwoJCQlJbnN0YWxsVHlwZSA9IElOU1RBTExUWVBFX05FVFdPUktfSU1BR0U7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2WyVkXSA9ICVzXG4iLCBpLCBhcmd2W2ldKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2W2ldOwoJCQlTdHJpbmdMaXN0QXBwZW5kKCZQcm9wZXJ0aWVzLCBBY3Rpb25BZG1pbik7CgkJfQoJCWVsc2UgaWYoIXN0cm5jYXNlY21wKGFyZ3ZbaV0sICIvZiIsIDIpKQoJCXsKCQkJaW50IGo7CgkJCWludCBsZW4gPSBzdHJsZW4oYXJndltpXSk7CgkJCUZ1bmN0aW9uUmVwYWlyID0gVFJVRTsKCQkJZm9yKGogPSAyOyBqIDwgbGVuOyBqKyspCgkJCXsKCQkJCXN3aXRjaChhcmd2W2ldW2pdKQoJCQkJewoJCQkJCWNhc2UgJ1AnOgoJCQkJCWNhc2UgJ3AnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRU1JU1NJTkc7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ08nOgoJCQkJCWNhc2UgJ28nOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRU9MREVSVkVSU0lPTjsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnRSc6CgkJCQkJY2FzZSAnZSc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFRVFVQUxWRVJTSU9OOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdEJzoKCQkJCQljYXNlICdkJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVFWEFDVDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnQyc6CgkJCQkJY2FzZSAnYyc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFVkVSSUZZOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdBJzoKCQkJCQljYXNlICdhJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVSRVBMQUNFOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdVJzoKCQkJCQljYXNlICd1JzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX1VTRVJEQVRBOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdNJzoKCQkJCQljYXNlICdtJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX01BQ0hJTkVEQVRBOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdTJzoKCQkJCQljYXNlICdzJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX1NIT1JUQ1VUOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdWJzoKCQkJCQljYXNlICd2JzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX1BBQ0tBR0U7CgkJCQkJCWJyZWFrOwoJCQkJCWRlZmF1bHQ6CgkJCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBvcHRpb24gXCIlY1wiIGluIFJlcGFpciBtb2RlXG4iLCBhcmd2W2ldW2pdKTsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaWYobGVuID09IDIpCgkJCXsKCQkJCVJlcGFpck1vZGUgPSBSRUlOU1RBTExNT0RFX0ZJTEVNSVNTSU5HIHwKCQkJCQlSRUlOU1RBTExNT0RFX0ZJTEVFUVVBTFZFUlNJT04gfAoJCQkJCVJFSU5TVEFMTE1PREVfRklMRVZFUklGWSB8CgkJCQkJUkVJTlNUQUxMTU9ERV9NQUNISU5FREFUQSB8CgkJCQkJUkVJTlNUQUxMTU9ERV9TSE9SVENVVDsKCQkJfQoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndlslZF0gPSAlc1xuIiwgaSwgYXJndltpXSk7CgkJCUdvdFByb2R1Y3RDb2RlID0gR2V0UHJvZHVjdENvZGUoYXJndltpXSwgJlBhY2thZ2VOYW1lLCAmUHJvZHVjdENvZGUpOwoJCX0KCQllbHNlIGlmKCFzdHJjYXNlY21wKGFyZ3ZbaV0sICIveCIpKQoJCXsKCQkJRnVuY3Rpb25JbnN0YWxsID0gVFJVRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZbJWRdID0gJXNcbiIsIGksIGFyZ3ZbaV0pOwoJCQlHb3RQcm9kdWN0Q29kZSA9IEdldFByb2R1Y3RDb2RlKGFyZ3ZbaV0sICZQYWNrYWdlTmFtZSwgJlByb2R1Y3RDb2RlKTsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmUHJvcGVydGllcywgUmVtb3ZlQWxsKTsKCQl9CgkJZWxzZSBpZighc3RybmNhc2VjbXAoYXJndltpXSwgIi9qIiwgMikpCgkJewoJCQlpbnQgajsKCQkJaW50IGxlbiA9IHN0cmxlbihhcmd2W2ldKTsKCQkJRnVuY3Rpb25BZHZlcnRpc2UgPSBUUlVFOwoJCQlmb3IoaiA9IDI7IGogPCBsZW47IGorKykKCQkJewoJCQkJc3dpdGNoKGFyZ3ZbaV1bal0pCgkJCQl7CgkJCQkJY2FzZSAnVSc6CgkJCQkJY2FzZSAndSc6CgkJCQkJCUFkdmVydGlzZU1vZGUgPSBBRFZFUlRJU0VGTEFHU19VU0VSQVNTSUdOOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdNJzoKCQkJCQljYXNlICdtJzoKCQkJCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX01BQ0hJTkVBU1NJR047CgkJCQkJCWJyZWFrOwoJCQkJCWRlZmF1bHQ6CgkJCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBvcHRpb24gXCIlY1wiIGluIEFkdmVydGlzZSBtb2RlXG4iLCBhcmd2W2ldW2pdKTsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZbJWRdID0gJXNcbiIsIGksIGFyZ3ZbaV0pOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZbaV07CgkJfQoJCWVsc2UgaWYoIXN0cmNhc2VjbXAoYXJndltpXSwgInUiKSkKCQl7CgkJCUZ1bmN0aW9uQWR2ZXJ0aXNlID0gVFJVRTsKCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX1VTRVJBU1NJR047CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2WyVkXSA9ICVzXG4iLCBpLCBhcmd2W2ldKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2W2ldOwoJCX0KCQllbHNlIGlmKCFzdHJjYXNlY21wKGFyZ3ZbaV0sICJtIikpCgkJewoJCQlGdW5jdGlvbkFkdmVydGlzZSA9IFRSVUU7CgkJCUFkdmVydGlzZU1vZGUgPSBBRFZFUlRJU0VGTEFHU19NQUNISU5FQVNTSUdOOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndlslZF0gPSAlc1xuIiwgaSwgYXJndltpXSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndltpXTsKCQl9CgkJZWxzZSBpZighc3RyY2FzZWNtcChhcmd2W2ldLCAiL3QiKSkKCQl7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2WyVkXSA9ICVzXG4iLCBpLCBhcmd2W2ldKTsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmVHJhbnNmb3JtcywgYXJndltpXSk7CgkJCVN0cmluZ0xpc3RBcHBlbmQoJlRyYW5zZm9ybXMsICI7Iik7CgkJfQoJCWVsc2UgaWYoIXN0cm5jYXNlY21wKGFyZ3ZbaV0sICJUUkFOU0ZPUk1TPSIsIDExKSkKCQl7CgkJCVN0cmluZ0xpc3RBcHBlbmQoJlRyYW5zZm9ybXMsIGFyZ3ZbaV0rMTEpOwoJCQlTdHJpbmdMaXN0QXBwZW5kKCZUcmFuc2Zvcm1zLCAiOyIpOwoJCX0KCQllbHNlIGlmKCFzdHJjYXNlY21wKGFyZ3ZbaV0sICIvZyIpKQoJCXsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZbJWRdID0gJXNcbiIsIGksIGFyZ3ZbaV0pOwoJCQlMYW5ndWFnZSA9IHN0cnRvbChhcmd2W2ldLCBOVUxMLCAwKTsKCQl9CgkJZWxzZSBpZighc3RybmNhc2VjbXAoYXJndltpXSwgIi9sIiwgMikpCgkJewoJCQlpbnQgajsKCQkJaW50IGxlbiA9IHN0cmxlbihhcmd2W2ldKTsKCQkJZm9yKGogPSAyOyBqIDwgbGVuOyBqKyspCgkJCXsKCQkJCXN3aXRjaChhcmd2W2ldW2pdKQoJCQkJewoJCQkJCWNhc2UgJ0knOgoJCQkJCWNhc2UgJ2knOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0lORk87CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1cnOgoJCQkJCWNhc2UgJ3cnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX1dBUk5JTkc7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0UnOgoJCQkJCWNhc2UgJ2UnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0VSUk9SOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdBJzoKCQkJCQljYXNlICdhJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9BQ1RJT05TVEFSVDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnUic6CgkJCQkJY2FzZSAncic6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfQUNUSU9OREFUQTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVSc6CgkJCQkJY2FzZSAndSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfVVNFUjsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnQyc6CgkJCQkJY2FzZSAnYyc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfQ09NTU9OREFUQTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnTSc6CgkJCQkJY2FzZSAnbSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfRkFUQUxFWElUOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdPJzoKCQkJCQljYXNlICdvJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9PVVRPRkRJU0tTUEFDRTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnUCc6CgkJCQkJY2FzZSAncCc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfUFJPUEVSVFlEVU1QOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdWJzoKCQkJCQljYXNlICd2JzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9WRVJCT1NFOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICcqJzoKCQkJCQkJTG9nTW9kZSA9IElOU1RBTExMT0dNT0RFX0ZBVEFMRVhJVCB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9FUlJPUiB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9XQVJOSU5HIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1VTRVIgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfSU5GTyB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9SRVNPTFZFU09VUkNFIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX09VVE9GRElTS1NQQUNFIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0FDVElPTlNUQVJUIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0FDVElPTkRBVEEgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfQ09NTU9OREFUQSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9QUk9QRVJUWURVTVAgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfUFJPR1JFU1MgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfSU5JVElBTElaRSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9URVJNSU5BVEUgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfU0hPV0RJQUxPRzsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnKyc6CgkJCQkJCUxvZ0F0dHJpYnV0ZXMgfD0gSU5TVEFMTExPR0FUVFJJQlVURVNfQVBQRU5EOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICchJzoKCQkJCQkJTG9nQXR0cmlidXRlcyB8PSBJTlNUQUxMTE9HQVRUUklCVVRFU19GTFVTSEVBQ0hMSU5FOwoJCQkJCQlicmVhazsKCQkJCQlkZWZhdWx0OgoJCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndlslZF0gPSAlc1xuIiwgaSwgYXJndltpXSk7CgkJCUxvZ0ZpbGVOYW1lID0gYXJndltpXTsKCQkJaWYoTXNpRW5hYmxlTG9nQShMb2dNb2RlLCBMb2dGaWxlTmFtZSwgTG9nQXR0cmlidXRlcykgIT0gRVJST1JfU1VDQ0VTUykKCQkJewoJCQkJZnByaW50ZihzdGRlcnIsICJMb2dnaW5nIGluICVzICgweCUwOGx4LCAlbHUpIGZhaWxlZFxuIiwgTG9nRmlsZU5hbWUsIExvZ01vZGUsIExvZ0F0dHJpYnV0ZXMpOwoJCQkJRXhpdFByb2Nlc3MoMSk7CgkJCX0KCQl9CgkJZWxzZSBpZighc3RyY2FzZWNtcChhcmd2W2ldLCAiL3AiKSkKCQl7CgkJCUZ1bmN0aW9uUGF0Y2ggPSBUUlVFOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndlslZF0gPSAlc1xuIiwgaSwgYXJndltpXSk7CgkJCVBhdGNoRmlsZU5hbWUgPSBhcmd2W2ldOwoJCX0KCQllbHNlIGlmKCFzdHJuY2FzZWNtcChhcmd2W2ldLCAiL3EiLCAyKSkKCQl7CgkJCWlmKHN0cmxlbihhcmd2W2ldKSA9PSAyIHx8ICFzdHJjYXNlY21wKGFyZ3ZbaV0rMiwgIm4iKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9OT05FOwoJCQl9CgkJCWVsc2UgaWYoIXN0cmNhc2VjbXAoYXJndltpXSsyLCAiYiIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0JBU0lDOwoJCQl9CgkJCWVsc2UgaWYoIXN0cmNhc2VjbXAoYXJndltpXSsyLCAiciIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX1JFRFVDRUQ7CgkJCX0KCQkJZWxzZSBpZighc3RyY2FzZWNtcChhcmd2W2ldKzIsICJmIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfRlVMTHxJTlNUQUxMVUlMRVZFTF9FTkRESUFMT0c7CgkJCX0KCQkJZWxzZSBpZighc3RyY2FzZWNtcChhcmd2W2ldKzIsICJuKyIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX05PTkV8SU5TVEFMTFVJTEVWRUxfRU5ERElBTE9HOwoJCQl9CgkJCWVsc2UgaWYoIXN0cmNhc2VjbXAoYXJndltpXSsyLCAiYisiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9CQVNJQ3xJTlNUQUxMVUlMRVZFTF9FTkRESUFMT0c7CgkJCX0KCQkJZWxzZSBpZighc3RyY2FzZWNtcChhcmd2W2ldKzIsICJiLSIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0JBU0lDfElOU1RBTExVSUxFVkVMX1BST0dSRVNTT05MWTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBvcHRpb24gXCIlc1wiIGZvciBVSSBsZXZlbFxuIiwgYXJndltpXSsyKTsKCQkJfQoJCQlyZXRJbnN0YWxsVUlMZXZlbCA9IE1zaVNldEludGVybmFsVUkoSW5zdGFsbFVJTGV2ZWwsIE5VTEwpOwoJCQlpZihyZXRJbnN0YWxsVUlMZXZlbCA9PSBJTlNUQUxMVUlMRVZFTF9OT0NIQU5HRSkKCQkJewoJCQkJZnByaW50ZihzdGRlcnIsICJTZXR0aW5nIHRoZSBVSSBsZXZlbCB0byAweCV4IGZhaWxlZC5cbiIsIEluc3RhbGxVSUxldmVsKTsKCQkJCUV4aXRQcm9jZXNzKDEpOwoJCQl9CgkJfQoJCWVsc2UgaWYoIXN0cmNhc2VjbXAoYXJndltpXSwgIi95IikpCgkJewoJCQlGdW5jdGlvbkRsbFJlZ2lzdGVyU2VydmVyID0gVFJVRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZbJWRdID0gJXNcbiIsIGksIGFyZ3ZbaV0pOwoJCQlEbGxOYW1lID0gYXJndltpXTsKCQl9CgkJZWxzZSBpZighc3RyY2FzZWNtcChhcmd2W2ldLCAiL3oiKSkKCQl7CgkJCUZ1bmN0aW9uRGxsVW5yZWdpc3RlclNlcnZlciA9IFRSVUU7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2WyVkXSA9ICVzXG4iLCBpLCBhcmd2W2ldKTsKCQkJRGxsTmFtZSA9IGFyZ3ZbaV07CgkJfQoJCWVsc2UgaWYoIXN0cmNhc2VjbXAoYXJndltpXSwgIi9oIikgfHwgIXN0cmNhc2VjbXAoYXJndltpXSwgIi8/IikpCgkJewoJCQlTaG93VXNhZ2UoMCk7CgkJfQoJCWVsc2UgaWYoc3RyY2hyKGFyZ3ZbaV0sICc9JykpCgkJewoJCQlTdHJpbmdMaXN0QXBwZW5kKCZQcm9wZXJ0aWVzLCBhcmd2W2ldKTsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmUHJvcGVydGllcywgIiAiKTsKCQl9CgkJZWxzZQoJCXsKCQkJRnVuY3Rpb25JbnN0YWxsID0gVFJVRTsKCQkJR290UHJvZHVjdENvZGUgPSBHZXRQcm9kdWN0Q29kZShhcmd2W2ldLCAmUGFja2FnZU5hbWUsICZQcm9kdWN0Q29kZSk7CgkJfQoJfQoKCVN0cmluZ0NvbXBhcmVSZW1vdmVMYXN0KFByb3BlcnRpZXMsICcgJyk7CglTdHJpbmdDb21wYXJlUmVtb3ZlTGFzdChUcmFuc2Zvcm1zLCAnOycpOwoKCWlmKEZ1bmN0aW9uSW5zdGFsbEFkbWluICYmIEZ1bmN0aW9uUGF0Y2gpCgkJRnVuY3Rpb25JbnN0YWxsID0gRkFMU0U7CgoJaWYoRnVuY3Rpb25JbnN0YWxsKQoJewoJCWlmKEdvdFByb2R1Y3RDb2RlKQoJCXsKCQkJV0lORV9GSVhNRSgiUHJvZHVjdCBjb2RlIHRyZWF0bWVudCBub3QgaW1wbGVtZW50ZWQgeWV0XG4iKTsKCQkJRXhpdFByb2Nlc3MoMSk7CgkJfQoJCWVsc2UKCQl7CgkJCWlmKE1zaUluc3RhbGxQcm9kdWN0QShQYWNrYWdlTmFtZSwgUHJvcGVydGllcykgIT0gRVJST1JfU1VDQ0VTUykKCQkJewoJCQkJZnByaW50ZihzdGRlcnIsICJJbnN0YWxsYXRpb24gb2YgJXMgKCVzKSBmYWlsZWQuXG4iLCBQYWNrYWdlTmFtZSwgUHJvcGVydGllcyk7CgkJCQlFeGl0UHJvY2VzcygxKTsKCQkJfQoJCX0KCX0KCWVsc2UgaWYoRnVuY3Rpb25SZXBhaXIpCgl7CgkJaWYoR290UHJvZHVjdENvZGUpCgkJewoJCQlXSU5FX0ZJWE1FKCJQcm9kdWN0IGNvZGUgdHJlYXRtZW50IG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiIpOwoJCQlFeGl0UHJvY2VzcygxKTsKCQl9CgkJZWxzZQoJCXsKCQkJaWYoTXNpUmVpbnN0YWxsUHJvZHVjdEEoUGFja2FnZU5hbWUsIFJlcGFpck1vZGUpICE9IEVSUk9SX1NVQ0NFU1MpCgkJCXsKCQkJCWZwcmludGYoc3RkZXJyLCAiUmVwYWlyIG9mICVzICgweCUwOGx4KSBmYWlsZWQuXG4iLCBQYWNrYWdlTmFtZSwgUmVwYWlyTW9kZSk7CgkJCQlFeGl0UHJvY2VzcygxKTsKCQkJfQoJCX0KCX0KCWVsc2UgaWYoRnVuY3Rpb25BZHZlcnRpc2UpCgl7CgkJaWYoTXNpQWR2ZXJ0aXNlUHJvZHVjdEEoUGFja2FnZU5hbWUsIChMUFNUUikgQWR2ZXJ0aXNlTW9kZSwgVHJhbnNmb3JtcywgTGFuZ3VhZ2UpICE9IEVSUk9SX1NVQ0NFU1MpCgkJewoJCQlmcHJpbnRmKHN0ZGVyciwgIkFkdmVydGlzaW5nIG9mICVzICglbHUsICVzLCAweCUwNHgpIGZhaWxlZC5cbiIsIFBhY2thZ2VOYW1lLCBBZHZlcnRpc2VNb2RlLCBUcmFuc2Zvcm1zLCBMYW5ndWFnZSk7CgkJCUV4aXRQcm9jZXNzKDEpOwoJCX0KCX0KCWVsc2UgaWYoRnVuY3Rpb25QYXRjaCkKCXsKCQlpZihNc2lBcHBseVBhdGNoQShQYXRjaEZpbGVOYW1lLCBQYWNrYWdlTmFtZSwgSW5zdGFsbFR5cGUsIFByb3BlcnRpZXMpICE9IEVSUk9SX1NVQ0NFU1MpCgkJewoJCQlmcHJpbnRmKHN0ZGVyciwgIlBhdGNoaW5nIHdpdGggJXMgKCVzLCAlZCwgJXMpXG4iLCBQYXRjaEZpbGVOYW1lLCBQYWNrYWdlTmFtZSwgSW5zdGFsbFR5cGUsIFByb3BlcnRpZXMpOwoJCQlFeGl0UHJvY2VzcygxKTsKCQl9Cgl9CgllbHNlIGlmKEZ1bmN0aW9uRGxsUmVnaXN0ZXJTZXJ2ZXIpCgl7CgkJRGxsUmVnaXN0ZXJTZXJ2ZXIoRGxsTmFtZSk7Cgl9CgllbHNlIGlmKEZ1bmN0aW9uRGxsVW5yZWdpc3RlclNlcnZlcikKCXsKCQlEbGxVbnJlZ2lzdGVyU2VydmVyKERsbE5hbWUpOwoJfQoJZWxzZQoJCVNob3dVc2FnZSgxKTsKCglyZXR1cm4gMDsKfQo=