LyoKICogbXNpZXhlYy5leGUgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDQgVmluY2VudCBC6XJvbgogKiBDb3B5cmlnaHQgMjAwNSBNaWtlIE1jQ29ybWFjawogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8d2luZG93cy5oPgojaW5jbHVkZSA8bXNpLmg+CiNpbmNsdWRlIDxvYmpiYXNlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgIm1zaWV4ZWMuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1zaWV4ZWMpOwoKc3RydWN0IHN0cmluZ19saXN0CnsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqbmV4dDsKCVdDSEFSIHN0clsxXTsKfTsKCnN0YXRpYyBjb25zdCBjaGFyIFVzYWdlU3RyW10gPQoiVXNhZ2U6XG4iCiIgIEluc3RhbGwgYSBwcm9kdWN0OlxuIgoiICAgIG1zaWV4ZWMge3BhY2thZ2V8cHJvZHVjdGNvZGV9IFtwcm9wZXJ0eV1cbiIKIiAgICBtc2lleGVjIC9pIHtwYWNrYWdlfHByb2R1Y3Rjb2RlfSBbcHJvcGVydHldXG4iCiIgICAgbXNpZXhlYyAvYSBwYWNrYWdlIFtwcm9wZXJ0eV1cbiIKIiAgUmVwYWlyIGFuIGluc3RhbGxhdGlvbjpcbiIKIiAgICBtc2lleGVjIC9mW3B8b3xlfGR8Y3xhfHV8bXxzfHZdIHtwYWNrYWdlfHByb2R1Y3Rjb2RlfVxuIgoiICBVbmluc3RhbGwgYSBwcm9kdWN0OlxuIgoiICAgIG1zaWV4ZWMgL3gge3BhY2thZ2V8cHJvZHVjdGNvZGV9IFtwcm9wZXJ0eV1cbiIKIiAgQWR2ZXJ0aXNlIGEgcHJvZHVjdDpcbiIKIiAgICBtc2lleGVjIC9qW3V8bV0gcGFja2FnZSBbL3QgdHJhbnNmb3JtXSBbL2cgbGFuZ3VhZ2VpZF1cbiIKIiAgICBtc2lleGVjIHt1fG19IHBhY2thZ2UgWy90IHRyYW5zZm9ybV0gWy9nIGxhbmd1YWdlaWRdXG4iCiIgIEFwcGx5IGEgcGF0Y2g6XG4iCiIgICAgbXNpZXhlYyAvcCBwYXRjaHBhY2thZ2UgW3Byb3BlcnR5XVxuIgoiICAgIG1zaWV4ZWMgL3AgcGF0Y2hwYWNrYWdlIC9hIHBhY2thZ2UgW3Byb3BlcnR5XVxuIgoiICBNb2RpZmllcnMgZm9yIGFib3ZlIG9wZXJhdGlvbnM6XG4iCiIgICAgbXNpZXhlYyAvbFsqXVtpfHd8ZXxhfHJ8dXxjfG18b3xwfHZ8XVsrfCFdIGxvZ2ZpbGVcbiIKIiAgICBtc2lleGVjIC9xe3xufGJ8cnxmfG4rfGIrfGItfVxuIgoiICBSZWdpc3RlciBhIG1vZHVsZTpcbiIKIiAgICBtc2lleGVjIC95IG1vZHVsZVxuIgoiICBVbnJlZ2lzdGVyIGEgbW9kdWxlOlxuIgoiICAgIG1zaWV4ZWMgL3ogbW9kdWxlXG4iCiIgIERpc3BsYXkgdXNhZ2UgYW5kIGNvcHlyaWdodDpcbiIKIiAgICBtc2lleGVjIHsvaHwvP31cbiIKIk5PVEU6IFByb2R1Y3QgY29kZSBvbiBjb21tYW5kbGluZSB1bmltcGxlbWVudGVkIGFzIG9mIHlldFxuIgoiXG4iCiJDb3B5cmlnaHQgMjAwNCBWaW5jZW50IELpcm9uXG4iOwoKc3RhdGljIGNvbnN0IFdDSEFSIEFjdGlvbkFkbWluW10gPSB7CiAgICdBJywnQycsJ1QnLCdJJywnTycsJ04nLCc9JywnQScsJ0QnLCdNJywnSScsJ04nLCcgJywwIH07CnN0YXRpYyBjb25zdCBXQ0hBUiBSZW1vdmVBbGxbXSA9IHsKICAgJ1InLCdFJywnTScsJ08nLCdWJywnRScsJz0nLCdBJywnTCcsJ0wnLCcgJywwIH07CgpzdGF0aWMgY29uc3QgV0NIQVIgSW5zdGFsbFJ1bk9uY2VbXSA9IHsKICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLAogICAnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1xcJywKICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXFwnLAogICAnSScsJ24nLCdzJywndCcsJ2EnLCdsJywnbCcsJ2UnLCdyJywnXFwnLAogICAnUicsJ3UnLCduJywnTycsJ24nLCdjJywnZScsJ0UnLCduJywndCcsJ3InLCdpJywnZScsJ3MnLDB9OwoKc3RhdGljIHZvaWQgU2hvd1VzYWdlKGludCBFeGl0Q29kZSkKewoJcHJpbnRmKFVzYWdlU3RyKTsKCUV4aXRQcm9jZXNzKEV4aXRDb2RlKTsKfQoKc3RhdGljIEJPT0wgSXNQcm9kdWN0Q29kZShMUFdTVFIgc3RyKQp7CglHVUlEIFByb2R1Y3RDb2RlOwoKCWlmKGxzdHJsZW5XKHN0cikgIT0gMzgpCgkJcmV0dXJuIEZBTFNFOwoJcmV0dXJuICggKENMU0lERnJvbVN0cmluZyhzdHIsICZQcm9kdWN0Q29kZSkgPT0gTk9FUlJPUikgKTsKCn0KCnN0YXRpYyBWT0lEIFN0cmluZ0xpc3RBcHBlbmQoc3RydWN0IHN0cmluZ19saXN0ICoqbGlzdCwgTFBDV1NUUiBzdHIpCnsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqZW50cnk7CglEV09SRCBzaXplOwoKCXNpemUgPSBzaXplb2YgKmVudHJ5ICsgbHN0cmxlblcoc3RyKSAqIHNpemVvZiAoV0NIQVIpOwoJZW50cnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CglpZighZW50cnkpCgl7CgkJV0lORV9FUlIoIk91dCBvZiBtZW1vcnkhXG4iKTsKCQlFeGl0UHJvY2VzcygxKTsKCX0KCWxzdHJjcHlXKGVudHJ5LT5zdHIsIHN0cik7CgllbnRyeS0+bmV4dCA9IE5VTEw7CgoJLyoKCSAqIElnbm9yaW5nIG8obl4yKSB0aW1lIGNvbXBsZXhpdHkgdG8gYWRkIG4gc3RyaW5ncyBmb3Igc2ltcGxpY2l0eSwKCSAqICBhZGQgdGhlIHN0cmluZyB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IHRvIHByZXNlcnZlIHRoZSBvcmRlci4KCSAqLwoJd2hpbGUoICpsaXN0ICkKCQlsaXN0ID0gJigqbGlzdCktPm5leHQ7CgkqbGlzdCA9IGVudHJ5Owp9CgpzdGF0aWMgTFBXU1RSIGJ1aWxkX3Byb3BlcnRpZXMoc3RydWN0IHN0cmluZ19saXN0ICpwcm9wZXJ0eV9saXN0KQp7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKmxpc3Q7CglMUFdTVFIgcmV0LCBwLCB2YWx1ZTsKCURXT1JEIGxlbjsKCUJPT0wgbmVlZHNfcXVvdGU7CgoJaWYoIXByb3BlcnR5X2xpc3QpCgkJcmV0dXJuIE5VTEw7CgoJLyogY291bnQgdGhlIHNwYWNlIHdlIG5lZWQgKi8KCWxlbiA9IDE7Cglmb3IobGlzdCA9IHByb3BlcnR5X2xpc3Q7IGxpc3Q7IGxpc3QgPSBsaXN0LT5uZXh0KQoJCWxlbiArPSBsc3RybGVuVyhsaXN0LT5zdHIpICsgMzsKCglyZXQgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbipzaXplb2YoV0NIQVIpICk7CgoJLyogYWRkIGEgc3BhY2UgYmVmb3JlIGVhY2ggc3RyaW5nLCBhbmQgcXVvdGUgdGhlIHZhbHVlICovCglwID0gcmV0OwoJZm9yKGxpc3QgPSBwcm9wZXJ0eV9saXN0OyBsaXN0OyBsaXN0ID0gbGlzdC0+bmV4dCkKCXsKCQl2YWx1ZSA9IHN0cmNoclcobGlzdC0+c3RyLCc9Jyk7CgkJaWYoIXZhbHVlKQoJCQljb250aW51ZTsKCQlsZW4gPSB2YWx1ZSAtIGxpc3QtPnN0cjsKCQkqcCsrID0gJyAnOwoJCXN0cm5jcHlXKHAsIGxpc3QtPnN0ciwgbGVuKTsKCQlwICs9IGxlbjsKCQkqcCsrID0gJz0nOwoKCQkvKiBjaGVjayBpZiB0aGUgdmFsdWUgY29udGFpbnMgc3BhY2VzIGFuZCBtYXliZSBxdW90ZSBpdCAqLwoJCXZhbHVlKys7CgkJbmVlZHNfcXVvdGUgPSBzdHJjaHJXKHZhbHVlLCcgJykgPyAxIDogMDsKCQlpZihuZWVkc19xdW90ZSkKCQkJKnArKyA9ICciJzsKCQlsZW4gPSBsc3RybGVuVyh2YWx1ZSk7CgkJc3RybmNweVcocCwgdmFsdWUsIGxlbik7CgkJcCArPSBsZW47CgkJaWYobmVlZHNfcXVvdGUpCgkJCSpwKysgPSAnIic7Cgl9CgkqcCA9IDA7CgoJV0lORV9UUkFDRSgicHJvcGVydGllcyAtPiAlc1xuIiwgd2luZV9kYmdzdHJfdyhyZXQpICk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIExQV1NUUiBidWlsZF90cmFuc2Zvcm1zKHN0cnVjdCBzdHJpbmdfbGlzdCAqdHJhbnNmb3JtX2xpc3QpCnsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqbGlzdDsKCUxQV1NUUiByZXQsIHA7CglEV09SRCBsZW47CgoJLyogY291bnQgdGhlIHNwYWNlIHdlIG5lZWQgKi8KCWxlbiA9IDE7Cglmb3IobGlzdCA9IHRyYW5zZm9ybV9saXN0OyBsaXN0OyBsaXN0ID0gbGlzdC0+bmV4dCkKCQlsZW4gKz0gbHN0cmxlblcobGlzdC0+c3RyKSArIDE7CgoJcmV0ID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKFdDSEFSKSApOwoKCS8qIGFkZCBhbGwgdGhlIHRyYW5zZm9ybXMgd2l0aCBhIHNlbWljb2xvbiBiZXR3ZWVuIGVhY2ggb25lICovCglwID0gcmV0OwoJZm9yKGxpc3QgPSB0cmFuc2Zvcm1fbGlzdDsgbGlzdDsgbGlzdCA9IGxpc3QtPm5leHQpCgl7CgkJbGVuID0gbHN0cmxlblcobGlzdC0+c3RyKTsKCQlsc3RyY3B5blcocCwgbGlzdC0+c3RyLCBsZW4gKTsKCQlwICs9IGxlbjsKCQlpZihsaXN0LT5uZXh0KQoJCQkqcCsrID0gJzsnOwoJfQoJKnAgPSAwOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBEV09SRCBtc2lfYXRvdShMUENXU1RSIHN0cikKewoJRFdPUkQgcmV0ID0gMDsKCXdoaWxlKCpzdHIgPj0gJzAnICYmICpzdHIgPD0gJzknKQoJewoJCXJldCAqPSAxMDsKCQlyZXQgKz0gKCpzdHIgLSAnMCcpOwoJCXN0cisrOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBMUFdTVFIgbXNpX3N0cmR1cChMUENXU1RSIHN0cikKewoJRFdPUkQgbGVuID0gbHN0cmxlblcoc3RyKSsxOwoJTFBXU1RSIHJldCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpKmxlbik7Cglsc3RyY3B5VyhyZXQsIHN0cik7CglyZXR1cm4gcmV0Owp9CgovKiBzdHIxIGlzIHRoZSBzYW1lIGFzIHN0cjIsIGlnbm9yaW5nIGNhc2UgKi8Kc3RhdGljIEJPT0wgbXNpX3N0cmVxdWFsKExQQ1dTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKCURXT1JEIGxlbiwgcmV0OwoJTFBXU1RSIHN0clc7CgoJbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCBzdHIyLCAtMSwgTlVMTCwgMCk7CglpZiggIWxlbiApCgkJcmV0dXJuIFRSVUU7CglpZiggbHN0cmxlblcoc3RyMSkgIT0gKGxlbi0xKSApCgkJcmV0dXJuIFRSVUU7CglzdHJXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXQ0hBUikqbGVuKTsKCU11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgc3RyMiwgLTEsIHN0clcsIGxlbik7CglyZXQgPSBDb21wYXJlU3RyaW5nVyhHZXRUaHJlYWRMb2NhbGUoKSwgTk9STV9JR05PUkVDQVNFLCBzdHIxLCBsZW4sIHN0clcsIGxlbik7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJXKTsKCXJldHVybiAocmV0ICE9IENTVFJfRVFVQUwpOwp9CgovKiBzdHIyIGlzIGF0IHRoZSBiZWdpbm5pbmcgb2Ygc3RyMSwgaWdub3JpbmcgY2FzZSAqLwpzdGF0aWMgQk9PTCBtc2lfc3RycHJlZml4KExQQ1dTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKCURXT1JEIGxlbiwgcmV0OwoJTFBXU1RSIHN0clc7CgoJbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCBzdHIyLCAtMSwgTlVMTCwgMCk7CglpZiggIWxlbiApCgkJcmV0dXJuIFRSVUU7CglpZiggbHN0cmxlblcoc3RyMSkgPCAobGVuLTEpICkKCQlyZXR1cm4gVFJVRTsKCXN0clcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSpsZW4pOwoJTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCBzdHIyLCAtMSwgc3RyVywgbGVuKTsKCXJldCA9IENvbXBhcmVTdHJpbmdXKEdldFRocmVhZExvY2FsZSgpLCBOT1JNX0lHTk9SRUNBU0UsIHN0cjEsIGxlbi0xLCBzdHJXLCBsZW4tMSk7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJXKTsKCXJldHVybiAocmV0ICE9IENTVFJfRVFVQUwpOwp9CgpzdGF0aWMgVk9JRCAqTG9hZFByb2MoTFBDV1NUUiBEbGxOYW1lLCBMUENTVFIgUHJvY05hbWUsIEhNT0RVTEUqIERsbEhhbmRsZSkKewoJVk9JRCogKCpwcm9jKSh2b2lkKTsKCgkqRGxsSGFuZGxlID0gTG9hZExpYnJhcnlFeFcoRGxsTmFtZSwgTlVMTCwgTE9BRF9XSVRIX0FMVEVSRURfU0VBUkNIX1BBVEgpOwoJaWYoISpEbGxIYW5kbGUpCgl7CgkJZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9hZCBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJCUV4aXRQcm9jZXNzKDEpOwoJfQoJcHJvYyA9IChWT0lEICopIEdldFByb2NBZGRyZXNzKCpEbGxIYW5kbGUsIFByb2NOYW1lKTsKCWlmKCFwcm9jKQoJewoJCWZwcmludGYoc3RkZXJyLCAiRGxsICVzIGRvZXMgbm90IGltcGxlbWVudCBmdW5jdGlvbiAlc1xuIiwKCQkJd2luZV9kYmdzdHJfdyhEbGxOYW1lKSwgUHJvY05hbWUpOwoJCUZyZWVMaWJyYXJ5KCpEbGxIYW5kbGUpOwoJCUV4aXRQcm9jZXNzKDEpOwoJfQoKCXJldHVybiBwcm9jOwp9CgpzdGF0aWMgRFdPUkQgRGxsUmVnaXN0ZXJTZXJ2ZXIoTFBDV1NUUiBEbGxOYW1lKQp7CglIUkVTVUxUIGhyOwoJRExMUkVHSVNURVJTRVJWRVIgcGZEbGxSZWdpc3RlclNlcnZlciA9IE5VTEw7CglITU9EVUxFIERsbEhhbmRsZSA9IE5VTEw7CgoJcGZEbGxSZWdpc3RlclNlcnZlciA9IExvYWRQcm9jKERsbE5hbWUsICJEbGxSZWdpc3RlclNlcnZlciIsICZEbGxIYW5kbGUpOwoKCWhyID0gcGZEbGxSZWdpc3RlclNlcnZlcigpOwoJaWYoRkFJTEVEKGhyKSkKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCB0byByZWdpc3RlciBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJCXJldHVybiAxOwoJfQoJcHJpbnRmKCJTdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJaWYoRGxsSGFuZGxlKQoJCUZyZWVMaWJyYXJ5KERsbEhhbmRsZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIERXT1JEIERsbFVucmVnaXN0ZXJTZXJ2ZXIoTFBDV1NUUiBEbGxOYW1lKQp7CglIUkVTVUxUIGhyOwoJRExMVU5SRUdJU1RFUlNFUlZFUiBwZkRsbFVucmVnaXN0ZXJTZXJ2ZXIgPSBOVUxMOwoJSE1PRFVMRSBEbGxIYW5kbGUgPSBOVUxMOwoKCXBmRGxsVW5yZWdpc3RlclNlcnZlciA9IExvYWRQcm9jKERsbE5hbWUsICJEbGxVbnJlZ2lzdGVyU2VydmVyIiwgJkRsbEhhbmRsZSk7CgoJaHIgPSBwZkRsbFVucmVnaXN0ZXJTZXJ2ZXIoKTsKCWlmKEZBSUxFRChocikpCgl7CgkJZnByaW50ZihzdGRlcnIsICJGYWlsZWQgdG8gdW5yZWdpc3RlciBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJCXJldHVybiAxOwoJfQoJcHJpbnRmKCJTdWNjZXNzZnVsbHkgdW5yZWdpc3RlcmVkIGRsbCAlc1xuIiwgd2luZV9kYmdzdHJfdyhEbGxOYW1lKSk7CglpZihEbGxIYW5kbGUpCgkJRnJlZUxpYnJhcnkoRGxsSGFuZGxlKTsKCXJldHVybiAwOwp9CgovKgogKiBzdGF0ZSBtYWNoaW5lIHRvIGJyZWFrIHVwIHRoZSBjb21tYW5kIGxpbmUgcHJvcGVybHkKICovCgplbnVtIGNob21wX3N0YXRlCnsKCWNzX3doaXRlc3BhY2UsCgljc190b2tlbiwKCWNzX3F1b3RlCn07CgpzdGF0aWMgaW50IGNob21wKCBXQ0hBUiAqc3RyICkKewoJZW51bSBjaG9tcF9zdGF0ZSBzdGF0ZSA9IGNzX3doaXRlc3BhY2U7CglXQ0hBUiAqcCwgKm91dDsKCWludCBjb3VudCA9IDAsIGlnbm9yZTsKCglmb3IoIHAgPSBzdHIsIG91dCA9IHN0cjsgKnA7IHArKyApCgl7CgkJaWdub3JlID0gMTsKCQlzd2l0Y2goIHN0YXRlICkKCQl7CgkJY2FzZSBjc193aGl0ZXNwYWNlOgoJCQlzd2l0Y2goICpwICkKCQkJewoJCQljYXNlICcgJzoKCQkJCWJyZWFrOwoJCQljYXNlICciJzoKCQkJCXN0YXRlID0gY3NfcXVvdGU7CgkJCQljb3VudCsrOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQljb3VudCsrOwoJCQkJaWdub3JlID0gMDsKCQkJCXN0YXRlID0gY3NfdG9rZW47CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgY3NfdG9rZW46CgkJCXN3aXRjaCggKnAgKQoJCQl7CgkJCWNhc2UgJyInOgoJCQkJc3RhdGUgPSBjc19xdW90ZTsKCQkJCWJyZWFrOwoJCQljYXNlICcgJzoKCQkJCXN0YXRlID0gY3Nfd2hpdGVzcGFjZTsKCQkJCSpvdXQrKyA9IDA7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWlnbm9yZSA9IDA7CgkJCX0KCQkJYnJlYWs7CgoJCWNhc2UgY3NfcXVvdGU6CgkJCXN3aXRjaCggKnAgKQoJCQl7CgkJCWNhc2UgJyInOgoJCQkJc3RhdGUgPSBjc190b2tlbjsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJaWdub3JlID0gMDsKCQkJfQoJCQlicmVhazsKCQl9CgkJaWYoICFpZ25vcmUgKQoJCQkqb3V0KysgPSAqcDsKCX0KCgkqb3V0ID0gMDsKCglyZXR1cm4gY291bnQ7Cn0KCnZvaWQgcHJvY2Vzc19hcmdzKCBXQ0hBUiAqY21kbGluZSwgaW50ICpwYXJnYywgV0NIQVIgKioqcGFyZ3YgKQp7CglXQ0hBUiAqKmFyZ3YsICpwID0gbXNpX3N0cmR1cChjbWRsaW5lKTsKCWludCBpLCBuOwoKCW4gPSBjaG9tcCggcCApOwoJYXJndiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YgKFdDSEFSKikqKG4rMSkpOwoJZm9yKCBpPTA7IGk8bjsgaSsrICkKCXsKCQlhcmd2W2ldID0gcDsKCQlwICs9IGxzdHJsZW5XKHApICsgMTsKCX0KCWFyZ3ZbaV0gPSBOVUxMOwoKCSpwYXJnYyA9IG47CgkqcGFyZ3YgPSBhcmd2Owp9CgpCT09MIHByb2Nlc3NfYXJnc19mcm9tX3JlZyggTFBXU1RSIGlkZW50LCBpbnQgKnBhcmdjLCBXQ0hBUiAqKipwYXJndiApCnsKCUxPTkcgcjsKCUhLRVkgaGtleSA9IDAsIGhrZXlBcmdzID0gMDsKCURXT1JEIHN6ID0gMCwgdHlwZSA9IDA7CglMUFdTVFIgYnVmID0gTlVMTDsKCUJPT0wgcmV0ID0gRkFMU0U7CgoJciA9IFJlZ09wZW5LZXlXKEhLRVlfTE9DQUxfTUFDSElORSwgSW5zdGFsbFJ1bk9uY2UsICZoa2V5KTsKCWlmKHIgIT0gRVJST1JfU1VDQ0VTUykKCQlyZXR1cm4gRkFMU0U7CglyID0gUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBpZGVudCwgMCwgJnR5cGUsIDAsICZzeik7CglpZihyID09IEVSUk9SX1NVQ0NFU1MgJiYgdHlwZSA9PSBSRUdfU1opCgl7CgkJYnVmID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN6KTsKCQlyID0gUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBpZGVudCwgMCwgJnR5cGUsIChMUEJZVEUpYnVmLCAmc3opOwoJCWlmKCByID09IEVSUk9SX1NVQ0NFU1MgKQoJCXsKCQkJcHJvY2Vzc19hcmdzKGJ1ZiwgcGFyZ2MsIHBhcmd2KTsKCQkJcmV0ID0gVFJVRTsKCQl9Cgl9CglSZWdDbG9zZUtleShoa2V5QXJncyk7CglyZXR1cm4gcmV0Owp9CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKCWludCBpOwoJQk9PTCBGdW5jdGlvbkluc3RhbGwgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25JbnN0YWxsQWRtaW4gPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25SZXBhaXIgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25BZHZlcnRpc2UgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25QYXRjaCA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvbkRsbFJlZ2lzdGVyU2VydmVyID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uRGxsVW5yZWdpc3RlclNlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvblJlZ1NlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvblVucmVnU2VydmVyID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uVW5rbm93biA9IEZBTFNFOwoKCUxQV1NUUiBQYWNrYWdlTmFtZSA9IE5VTEw7CglMUFdTVFIgUHJvcGVydGllcyA9IE5VTEw7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKnByb3BlcnR5X2xpc3QgPSBOVUxMOwoKCURXT1JEIFJlcGFpck1vZGUgPSAwOwoKCURXT1JEIEFkdmVydGlzZU1vZGUgPSAwOwoJTFBXU1RSIFRyYW5zZm9ybXMgPSBOVUxMOwoJc3RydWN0IHN0cmluZ19saXN0ICp0cmFuc2Zvcm1fbGlzdCA9IE5VTEw7CglMQU5HSUQgTGFuZ3VhZ2UgPSAwOwoKCURXT1JEIExvZ01vZGUgPSAwOwoJTFBXU1RSIExvZ0ZpbGVOYW1lID0gTlVMTDsKCURXT1JEIExvZ0F0dHJpYnV0ZXMgPSAwOwoKCUxQV1NUUiBQYXRjaEZpbGVOYW1lID0gTlVMTDsKCUlOU1RBTExUWVBFIEluc3RhbGxUeXBlID0gSU5TVEFMTFRZUEVfREVGQVVMVDsKCglJTlNUQUxMVUlMRVZFTCBJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0ZVTEw7CgoJTFBXU1RSIERsbE5hbWUgPSBOVUxMOwoJRFdPUkQgUmV0dXJuQ29kZTsKCUxQV1NUUiAqYXJndlcgPSBOVUxMOwoKCS8qIG92ZXJ3cml0ZSB0aGUgY29tbWFuZCBsaW5lICovCglwcm9jZXNzX2FyZ3MoIEdldENvbW1hbmRMaW5lVygpLCAmYXJnYywgJmFyZ3ZXICk7CgoJLyoKCSAqIElmIHRoZSBhcmdzIGJlZ2luIHdpdGggL0AgSURFTlQgdGhlbiB3ZSBuZWVkIHRvIGxvYWQgdGhlIHJlYWwKCSAqIGNvbW1hbmQgbGluZSBvdXQgb2YgdGhlIFJ1bk9uY2VFbnRyaWVzIGtleSBpbiB0aGUgcmVnaXN0cnkuCgkgKiAgV2UgZG8gdGhhdCBiZWZvcmUgc3RhcnRpbmcgdG8gcHJvY2VzcyB0aGUgcmVhbCBjb21tYW5kbGluZSwKCSAqIHRoZW4gb3ZlcndyaXRlIHRoZSBjb21tYW5kbGluZSBhZ2Fpbi4KCSAqLwoJaWYoIW1zaV9zdHJlcXVhbChhcmd2V1sxXSwgIi9AIikpCgl7CgkJaWYoIXByb2Nlc3NfYXJnc19mcm9tX3JlZyggYXJndldbMl0sICZhcmdjLCAmYXJndlcgKSkKCQkJcmV0dXJuIDE7Cgl9CgoJZm9yKGkgPSAxOyBpIDwgYXJnYzsgaSsrKQoJewoJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgoJCWlmICghbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL3JlZ3NlcnZlciIpKQoJCXsKCQkJRnVuY3Rpb25SZWdTZXJ2ZXIgPSBUUlVFOwoJCX0KCQllbHNlIGlmICghbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL3VucmVnc2VydmVyIikgfHwgIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi91bnJlZ2lzdGVyIikpCgkJewoJCQlGdW5jdGlvblVucmVnU2VydmVyID0gVFJVRTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cnByZWZpeChhcmd2V1tpXSwgIi9pIikpCgkJewoJCQlMUFdTVFIgYXJndldpID0gYXJndldbaV07CgkJCUZ1bmN0aW9uSW5zdGFsbCA9IFRSVUU7CgkJCWlmKGxzdHJsZW5XKGFyZ3ZXaSkgPiAyKQoJCQkJYXJndldpICs9IDI7CgkJCWVsc2UKCQkJewoJCQkJaSsrOwoJCQkJaWYoaSA+PSBhcmdjKQoJCQkJCVNob3dVc2FnZSgxKTsKCQkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCQlhcmd2V2kgPSBhcmd2V1tpXTsKCQkJfQoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXaTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL2EiKSkKCQl7CgkJCUZ1bmN0aW9uSW5zdGFsbCA9IFRSVUU7CgkJCUZ1bmN0aW9uSW5zdGFsbEFkbWluID0gVFJVRTsKCQkJSW5zdGFsbFR5cGUgPSBJTlNUQUxMVFlQRV9ORVRXT1JLX0lNQUdFOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXTsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmcHJvcGVydHlfbGlzdCwgQWN0aW9uQWRtaW4pOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RycHJlZml4KGFyZ3ZXW2ldLCAiL2YiKSkKCQl7CgkJCWludCBqOwoJCQlpbnQgbGVuID0gbHN0cmxlblcoYXJndldbaV0pOwoJCQlGdW5jdGlvblJlcGFpciA9IFRSVUU7CgkJCWZvcihqID0gMjsgaiA8IGxlbjsgaisrKQoJCQl7CgkJCQlzd2l0Y2goYXJndldbaV1bal0pCgkJCQl7CgkJCQkJY2FzZSAnUCc6CgkJCQkJY2FzZSAncCc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFTUlTU0lORzsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnTyc6CgkJCQkJY2FzZSAnbyc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFT0xERVJWRVJTSU9OOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdFJzoKCQkJCQljYXNlICdlJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVFUVVBTFZFUlNJT047CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0QnOgoJCQkJCWNhc2UgJ2QnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRUVYQUNUOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdDJzoKCQkJCQljYXNlICdjJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVWRVJJRlk7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0EnOgoJCQkJCWNhc2UgJ2EnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRVJFUExBQ0U7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1UnOgoJCQkJCWNhc2UgJ3UnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfVVNFUkRBVEE7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ00nOgoJCQkJCWNhc2UgJ20nOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfTUFDSElORURBVEE7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1MnOgoJCQkJCWNhc2UgJ3MnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfU0hPUlRDVVQ7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1YnOgoJCQkJCWNhc2UgJ3YnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfUEFDS0FHRTsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIG9wdGlvbiBcIiVjXCIgaW4gUmVwYWlyIG1vZGVcbiIsIGFyZ3ZXW2ldW2pdKTsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaWYobGVuID09IDIpCgkJCXsKCQkJCVJlcGFpck1vZGUgPSBSRUlOU1RBTExNT0RFX0ZJTEVNSVNTSU5HIHwKCQkJCQlSRUlOU1RBTExNT0RFX0ZJTEVFUVVBTFZFUlNJT04gfAoJCQkJCVJFSU5TVEFMTE1PREVfRklMRVZFUklGWSB8CgkJCQkJUkVJTlNUQUxMTU9ERV9NQUNISU5FREFUQSB8CgkJCQkJUkVJTlNUQUxMTU9ERV9TSE9SVENVVDsKCQkJfQoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL3giKSkKCQl7CgkJCUZ1bmN0aW9uSW5zdGFsbCA9IFRSVUU7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCQlTdHJpbmdMaXN0QXBwZW5kKCZwcm9wZXJ0eV9saXN0LCBSZW1vdmVBbGwpOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RycHJlZml4KGFyZ3ZXW2ldLCAiL2oiKSkKCQl7CgkJCWludCBqOwoJCQlpbnQgbGVuID0gbHN0cmxlblcoYXJndldbaV0pOwoJCQlGdW5jdGlvbkFkdmVydGlzZSA9IFRSVUU7CgkJCWZvcihqID0gMjsgaiA8IGxlbjsgaisrKQoJCQl7CgkJCQlzd2l0Y2goYXJndldbaV1bal0pCgkJCQl7CgkJCQkJY2FzZSAnVSc6CgkJCQkJY2FzZSAndSc6CgkJCQkJCUFkdmVydGlzZU1vZGUgPSBBRFZFUlRJU0VGTEFHU19VU0VSQVNTSUdOOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdNJzoKCQkJCQljYXNlICdtJzoKCQkJCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX01BQ0hJTkVBU1NJR047CgkJCQkJCWJyZWFrOwoJCQkJCWRlZmF1bHQ6CgkJCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBvcHRpb24gXCIlY1wiIGluIEFkdmVydGlzZSBtb2RlXG4iLCBhcmd2V1tpXVtqXSk7CgkJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICJ1IikpCgkJewoJCQlGdW5jdGlvbkFkdmVydGlzZSA9IFRSVUU7CgkJCUFkdmVydGlzZU1vZGUgPSBBRFZFUlRJU0VGTEFHU19VU0VSQVNTSUdOOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAibSIpKQoJCXsKCQkJRnVuY3Rpb25BZHZlcnRpc2UgPSBUUlVFOwoJCQlBZHZlcnRpc2VNb2RlID0gQURWRVJUSVNFRkxBR1NfTUFDSElORUFTU0lHTjsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi90IikpCgkJewoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmdHJhbnNmb3JtX2xpc3QsIGFyZ3ZXW2ldKTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cnByZWZpeChhcmd2V1tpXSwgIlRSQU5TRk9STVM9IikpCgkJewoJCQlTdHJpbmdMaXN0QXBwZW5kKCZ0cmFuc2Zvcm1fbGlzdCwgYXJndldbaV0rMTEpOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvZyIpKQoJCXsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCUxhbmd1YWdlID0gbXNpX2F0b3UoYXJndldbaV0pOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RycHJlZml4KGFyZ3ZXW2ldLCAiL2wiKSkKCQl7CgkJCWludCBqOwoJCQlpbnQgbGVuID0gbHN0cmxlblcoYXJndldbaV0pOwoJCQlmb3IoaiA9IDI7IGogPCBsZW47IGorKykKCQkJewoJCQkJc3dpdGNoKGFyZ3ZXW2ldW2pdKQoJCQkJewoJCQkJCWNhc2UgJ0knOgoJCQkJCWNhc2UgJ2knOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0lORk87CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1cnOgoJCQkJCWNhc2UgJ3cnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX1dBUk5JTkc7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0UnOgoJCQkJCWNhc2UgJ2UnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0VSUk9SOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdBJzoKCQkJCQljYXNlICdhJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9BQ1RJT05TVEFSVDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnUic6CgkJCQkJY2FzZSAncic6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfQUNUSU9OREFUQTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVSc6CgkJCQkJY2FzZSAndSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfVVNFUjsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnQyc6CgkJCQkJY2FzZSAnYyc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfQ09NTU9OREFUQTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnTSc6CgkJCQkJY2FzZSAnbSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfRkFUQUxFWElUOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdPJzoKCQkJCQljYXNlICdvJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9PVVRPRkRJU0tTUEFDRTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnUCc6CgkJCQkJY2FzZSAncCc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfUFJPUEVSVFlEVU1QOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdWJzoKCQkJCQljYXNlICd2JzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9WRVJCT1NFOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICcqJzoKCQkJCQkJTG9nTW9kZSA9IElOU1RBTExMT0dNT0RFX0ZBVEFMRVhJVCB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9FUlJPUiB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9XQVJOSU5HIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1VTRVIgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfSU5GTyB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9SRVNPTFZFU09VUkNFIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX09VVE9GRElTS1NQQUNFIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0FDVElPTlNUQVJUIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0FDVElPTkRBVEEgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfQ09NTU9OREFUQSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9QUk9QRVJUWURVTVAgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfUFJPR1JFU1MgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfSU5JVElBTElaRSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9URVJNSU5BVEUgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfU0hPV0RJQUxPRzsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnKyc6CgkJCQkJCUxvZ0F0dHJpYnV0ZXMgfD0gSU5TVEFMTExPR0FUVFJJQlVURVNfQVBQRU5EOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICchJzoKCQkJCQkJTG9nQXR0cmlidXRlcyB8PSBJTlNUQUxMTE9HQVRUUklCVVRFU19GTFVTSEVBQ0hMSU5FOwoJCQkJCQlicmVhazsKCQkJCQlkZWZhdWx0OgoJCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJTG9nRmlsZU5hbWUgPSBhcmd2V1tpXTsKCQkJaWYoTXNpRW5hYmxlTG9nVyhMb2dNb2RlLCBMb2dGaWxlTmFtZSwgTG9nQXR0cmlidXRlcykgIT0gRVJST1JfU1VDQ0VTUykKCQkJewoJCQkJZnByaW50ZihzdGRlcnIsICJMb2dnaW5nIGluICVzICgweCUwOGx4LCAlbHUpIGZhaWxlZFxuIiwKCQkJCQkgd2luZV9kYmdzdHJfdyhMb2dGaWxlTmFtZSksIExvZ01vZGUsIExvZ0F0dHJpYnV0ZXMpOwoJCQkJRXhpdFByb2Nlc3MoMSk7CgkJCX0KCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL3AiKSkKCQl7CgkJCUZ1bmN0aW9uUGF0Y2ggPSBUUlVFOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJUGF0Y2hGaWxlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RycHJlZml4KGFyZ3ZXW2ldLCAiL3EiKSkKCQl7CgkJCWlmKGxzdHJsZW5XKGFyZ3ZXW2ldKSA9PSAyIHx8ICFtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgIm4iKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9OT05FOwoJCQl9CgkJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiYiIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0JBU0lDOwoJCQl9CgkJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiciIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX1JFRFVDRUQ7CgkJCX0KCQkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJmIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfRlVMTHxJTlNUQUxMVUlMRVZFTF9FTkRESUFMT0c7CgkJCX0KCQkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJuKyIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX05PTkV8SU5TVEFMTFVJTEVWRUxfRU5ERElBTE9HOwoJCQl9CgkJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiYisiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9CQVNJQ3xJTlNUQUxMVUlMRVZFTF9FTkRESUFMT0c7CgkJCX0KCQkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJiLSIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0JBU0lDfElOU1RBTExVSUxFVkVMX1BST0dSRVNTT05MWTsKCQkJfQoJCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgImIrISIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0JBU0lDfElOU1RBTExVSUxFVkVMX0VORERJQUxPRzsKCQkJCVdJTkVfRklYTUUoIlVua25vd24gbW9kaWZpZXI6ICFcbiIpOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIG9wdGlvbiBcIiVzXCIgZm9yIFVJIGxldmVsXG4iLAoJCQkJCSB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKzIpKTsKCQkJfQoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIveSIpKQoJCXsKCQkJRnVuY3Rpb25EbGxSZWdpc3RlclNlcnZlciA9IFRSVUU7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlEbGxOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi96IikpCgkJewoJCQlGdW5jdGlvbkRsbFVucmVnaXN0ZXJTZXJ2ZXIgPSBUUlVFOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJRGxsTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvaCIpIHx8ICFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvPyIpKQoJCXsKCQkJU2hvd1VzYWdlKDApOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvbSIpKQoJCXsKCQkJRnVuY3Rpb25Vbmtub3duID0gVFJVRTsKCQkJV0lORV9GSVhNRSgiVW5rbm93biBwYXJhbWV0ZXIgL21cbiIpOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvRCIpKQoJCXsKCQkJRnVuY3Rpb25Vbmtub3duID0gVFJVRTsKCQkJV0lORV9GSVhNRSgiVW5rbm93biBwYXJhbWV0ZXIgL0RcbiIpOwoJCX0KCQllbHNlIGlmKHN0cmNoclcoYXJndldbaV0sICc9JykpCgkJewoJCQlTdHJpbmdMaXN0QXBwZW5kKCZwcm9wZXJ0eV9saXN0LCBhcmd2V1tpXSk7CgkJfQoJCWVsc2UKCQl7CgkJCUZ1bmN0aW9uSW5zdGFsbCA9IFRSVUU7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJfQoJfQoKCS8qIHN0YXJ0IHRoZSBHVUkgKi8KCU1zaVNldEludGVybmFsVUkoSW5zdGFsbFVJTGV2ZWwsIE5VTEwpOwoKCVByb3BlcnRpZXMgPSBidWlsZF9wcm9wZXJ0aWVzKCBwcm9wZXJ0eV9saXN0ICk7CglUcmFuc2Zvcm1zID0gYnVpbGRfdHJhbnNmb3JtcyggdHJhbnNmb3JtX2xpc3QgKTsKCglpZihGdW5jdGlvbkluc3RhbGxBZG1pbiAmJiBGdW5jdGlvblBhdGNoKQoJCUZ1bmN0aW9uSW5zdGFsbCA9IEZBTFNFOwoKCVJldHVybkNvZGUgPSAxOwoJaWYoRnVuY3Rpb25JbnN0YWxsKQoJewoJCWlmKElzUHJvZHVjdENvZGUoUGFja2FnZU5hbWUpKQoJCQlSZXR1cm5Db2RlID0gTXNpQ29uZmlndXJlUHJvZHVjdEV4VyhQYWNrYWdlTmFtZSwgMCwgSU5TVEFMTFNUQVRFX0RFRkFVTFQsIFByb3BlcnRpZXMpOwoJCWVsc2UKCQkJUmV0dXJuQ29kZSA9IE1zaUluc3RhbGxQcm9kdWN0VyhQYWNrYWdlTmFtZSwgUHJvcGVydGllcyk7Cgl9CgllbHNlIGlmKEZ1bmN0aW9uUmVwYWlyKQoJewoJCWlmKElzUHJvZHVjdENvZGUoUGFja2FnZU5hbWUpKQoJCQlXSU5FX0ZJWE1FKCJQcm9kdWN0IGNvZGUgdHJlYXRtZW50IG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiIpOwoJCWVsc2UKCQkJUmV0dXJuQ29kZSA9IE1zaVJlaW5zdGFsbFByb2R1Y3RXKFBhY2thZ2VOYW1lLCBSZXBhaXJNb2RlKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25BZHZlcnRpc2UpCgl7CgkJUmV0dXJuQ29kZSA9IE1zaUFkdmVydGlzZVByb2R1Y3RXKFBhY2thZ2VOYW1lLCAoTFBXU1RSKSBBZHZlcnRpc2VNb2RlLCBUcmFuc2Zvcm1zLCBMYW5ndWFnZSk7Cgl9CgllbHNlIGlmKEZ1bmN0aW9uUGF0Y2gpCgl7CgkJUmV0dXJuQ29kZSA9IE1zaUFwcGx5UGF0Y2hXKFBhdGNoRmlsZU5hbWUsIFBhY2thZ2VOYW1lLCBJbnN0YWxsVHlwZSwgUHJvcGVydGllcyk7Cgl9CgllbHNlIGlmKEZ1bmN0aW9uRGxsUmVnaXN0ZXJTZXJ2ZXIpCgl7CgkJUmV0dXJuQ29kZSA9IERsbFJlZ2lzdGVyU2VydmVyKERsbE5hbWUpOwoJfQoJZWxzZSBpZihGdW5jdGlvbkRsbFVucmVnaXN0ZXJTZXJ2ZXIpCgl7CgkJUmV0dXJuQ29kZSA9IERsbFVucmVnaXN0ZXJTZXJ2ZXIoRGxsTmFtZSk7Cgl9CgllbHNlIGlmIChGdW5jdGlvblJlZ1NlcnZlcikKCXsKCQlXSU5FX0ZJWE1FKCAiL3JlZ3NlcnZlciBub3QgaW1wbGVtZW50ZWQgeWV0LCBpZ25vcmluZ1xuIiApOwoJfQoJZWxzZSBpZiAoRnVuY3Rpb25VbnJlZ1NlcnZlcikKCXsKCQlXSU5FX0ZJWE1FKCAiL3VucmVnc2VydmVyIG5vdCBpbXBsZW1lbnRlZCB5ZXQsIGlnbm9yaW5nXG4iICk7Cgl9CgllbHNlIGlmIChGdW5jdGlvblVua25vd24pCgl7CgkJV0lORV9GSVhNRSggIlVua25vd24gZnVuY3Rpb24sIGlnbm9yaW5nXG4iICk7Cgl9CgllbHNlCgkJU2hvd1VzYWdlKDEpOwoKCXJldHVybiBSZXR1cm5Db2RlOwp9Cg==