LyoKICogbXNpZXhlYy5leGUgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDQgVmluY2VudCBC6XJvbgogKiBDb3B5cmlnaHQgMjAwNSBNaWtlIE1jQ29ybWFjawogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojZGVmaW5lIFdJTjMyX0xFQU5fQU5EX01FQU4KCiNpbmNsdWRlIDx3aW5kb3dzLmg+CiNpbmNsdWRlIDxtc2kuaD4KI2luY2x1ZGUgPG9iamJhc2UuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChtc2lleGVjKTsKCnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpETExSRUdJU1RFUlNFUlZFUikodm9pZCk7CnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpETExVTlJFR0lTVEVSU0VSVkVSKSh2b2lkKTsKCnN0cnVjdCBzdHJpbmdfbGlzdAp7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKm5leHQ7CglXQ0hBUiBzdHJbMV07Cn07CgpzdGF0aWMgY29uc3QgY2hhciBVc2FnZVN0cltdID0KIlVzYWdlOlxuIgoiICBJbnN0YWxsIGEgcHJvZHVjdDpcbiIKIiAgICBtc2lleGVjIHtwYWNrYWdlfHByb2R1Y3Rjb2RlfSBbcHJvcGVydHldXG4iCiIgICAgbXNpZXhlYyAvaSB7cGFja2FnZXxwcm9kdWN0Y29kZX0gW3Byb3BlcnR5XVxuIgoiICAgIG1zaWV4ZWMgL2EgcGFja2FnZSBbcHJvcGVydHldXG4iCiIgIFJlcGFpciBhbiBpbnN0YWxsYXRpb246XG4iCiIgICAgbXNpZXhlYyAvZltwfG98ZXxkfGN8YXx1fG18c3x2XSB7cGFja2FnZXxwcm9kdWN0Y29kZX1cbiIKIiAgVW5pbnN0YWxsIGEgcHJvZHVjdDpcbiIKIiAgICBtc2lleGVjIC94IHtwYWNrYWdlfHByb2R1Y3Rjb2RlfSBbcHJvcGVydHldXG4iCiIgIEFkdmVydGlzZSBhIHByb2R1Y3Q6XG4iCiIgICAgbXNpZXhlYyAvalt1fG1dIHBhY2thZ2UgWy90IHRyYW5zZm9ybV0gWy9nIGxhbmd1YWdlaWRdXG4iCiIgICAgbXNpZXhlYyB7dXxtfSBwYWNrYWdlIFsvdCB0cmFuc2Zvcm1dIFsvZyBsYW5ndWFnZWlkXVxuIgoiICBBcHBseSBhIHBhdGNoOlxuIgoiICAgIG1zaWV4ZWMgL3AgcGF0Y2hwYWNrYWdlIFtwcm9wZXJ0eV1cbiIKIiAgICBtc2lleGVjIC9wIHBhdGNocGFja2FnZSAvYSBwYWNrYWdlIFtwcm9wZXJ0eV1cbiIKIiAgTW9kaWZpZXJzIGZvciBhYm92ZSBvcGVyYXRpb25zOlxuIgoiICAgIG1zaWV4ZWMgL2xbKl1baXx3fGV8YXxyfHV8Y3xtfG98cHx2fF1bK3whXSBsb2dmaWxlXG4iCiIgICAgbXNpZXhlYyAvcXt8bnxifHJ8ZnxuK3xiK3xiLX1cbiIKIiAgUmVnaXN0ZXIgYSBtb2R1bGU6XG4iCiIgICAgbXNpZXhlYyAveSBtb2R1bGVcbiIKIiAgVW5yZWdpc3RlciBhIG1vZHVsZTpcbiIKIiAgICBtc2lleGVjIC96IG1vZHVsZVxuIgoiICBEaXNwbGF5IHVzYWdlIGFuZCBjb3B5cmlnaHQ6XG4iCiIgICAgbXNpZXhlYyB7L2h8Lz99XG4iCiJOT1RFOiBQcm9kdWN0IGNvZGUgb24gY29tbWFuZGxpbmUgdW5pbXBsZW1lbnRlZCBhcyBvZiB5ZXRcbiIKIlxuIgoiQ29weXJpZ2h0IDIwMDQgVmluY2VudCBC6XJvblxuIjsKCnN0YXRpYyBjb25zdCBXQ0hBUiBBY3Rpb25BZG1pbltdID0gewogICAnQScsJ0MnLCdUJywnSScsJ08nLCdOJywnPScsJ0EnLCdEJywnTScsJ0knLCdOJywwIH07CnN0YXRpYyBjb25zdCBXQ0hBUiBSZW1vdmVBbGxbXSA9IHsKICAgJ1InLCdFJywnTScsJ08nLCdWJywnRScsJz0nLCdBJywnTCcsJ0wnLDAgfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBJbnN0YWxsUnVuT25jZVtdID0gewogICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsCiAgICdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcXCcsCiAgICdJJywnbicsJ3MnLCd0JywnYScsJ2wnLCdsJywnZScsJ3InLCdcXCcsCiAgICdSJywndScsJ24nLCdPJywnbicsJ2MnLCdlJywnRScsJ24nLCd0JywncicsJ2knLCdlJywncycsMH07CgpzdGF0aWMgdm9pZCBTaG93VXNhZ2UoaW50IEV4aXRDb2RlKQp7CglwcmludGYoVXNhZ2VTdHIpOwoJRXhpdFByb2Nlc3MoRXhpdENvZGUpOwp9CgpzdGF0aWMgQk9PTCBJc1Byb2R1Y3RDb2RlKExQV1NUUiBzdHIpCnsKCUdVSUQgUHJvZHVjdENvZGU7CgoJaWYobHN0cmxlblcoc3RyKSAhPSAzOCkKCQlyZXR1cm4gRkFMU0U7CglyZXR1cm4gKCAoQ0xTSURGcm9tU3RyaW5nKHN0ciwgJlByb2R1Y3RDb2RlKSA9PSBOT0VSUk9SKSApOwoKfQoKc3RhdGljIFZPSUQgU3RyaW5nTGlzdEFwcGVuZChzdHJ1Y3Qgc3RyaW5nX2xpc3QgKipsaXN0LCBMUENXU1RSIHN0cikKewoJc3RydWN0IHN0cmluZ19saXN0ICplbnRyeTsKCURXT1JEIHNpemU7CgoJc2l6ZSA9IHNpemVvZiAqZW50cnkgKyBsc3RybGVuVyhzdHIpICogc2l6ZW9mIChXQ0hBUik7CgllbnRyeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKCWlmKCFlbnRyeSkKCXsKCQlXSU5FX0VSUigiT3V0IG9mIG1lbW9yeSFcbiIpOwoJCUV4aXRQcm9jZXNzKDEpOwoJfQoJbHN0cmNweVcoZW50cnktPnN0ciwgc3RyKTsKCWVudHJ5LT5uZXh0ID0gTlVMTDsKCgkvKgoJICogSWdub3JpbmcgbyhuXjIpIHRpbWUgY29tcGxleGl0eSB0byBhZGQgbiBzdHJpbmdzIGZvciBzaW1wbGljaXR5LAoJICogIGFkZCB0aGUgc3RyaW5nIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QgdG8gcHJlc2VydmUgdGhlIG9yZGVyLgoJICovCgl3aGlsZSggKmxpc3QgKQoJCWxpc3QgPSAmKCpsaXN0KS0+bmV4dDsKCSpsaXN0ID0gZW50cnk7Cn0KCnN0YXRpYyBMUFdTVFIgYnVpbGRfcHJvcGVydGllcyhzdHJ1Y3Qgc3RyaW5nX2xpc3QgKnByb3BlcnR5X2xpc3QpCnsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqbGlzdDsKCUxQV1NUUiByZXQsIHAsIHZhbHVlOwoJRFdPUkQgbGVuOwoJQk9PTCBuZWVkc19xdW90ZTsKCglpZighcHJvcGVydHlfbGlzdCkKCQlyZXR1cm4gTlVMTDsKCgkvKiBjb3VudCB0aGUgc3BhY2Ugd2UgbmVlZCAqLwoJbGVuID0gMTsKCWZvcihsaXN0ID0gcHJvcGVydHlfbGlzdDsgbGlzdDsgbGlzdCA9IGxpc3QtPm5leHQpCgkJbGVuICs9IGxzdHJsZW5XKGxpc3QtPnN0cikgKyAzOwoKCXJldCA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikgKTsKCgkvKiBhZGQgYSBzcGFjZSBiZWZvcmUgZWFjaCBzdHJpbmcsIGFuZCBxdW90ZSB0aGUgdmFsdWUgKi8KCXAgPSByZXQ7Cglmb3IobGlzdCA9IHByb3BlcnR5X2xpc3Q7IGxpc3Q7IGxpc3QgPSBsaXN0LT5uZXh0KQoJewoJCXZhbHVlID0gc3RyY2hyVyhsaXN0LT5zdHIsJz0nKTsKCQlpZighdmFsdWUpCgkJCWNvbnRpbnVlOwoJCWxlbiA9IHZhbHVlIC0gbGlzdC0+c3RyOwoJCSpwKysgPSAnICc7CgkJbWVtY3B5KHAsIGxpc3QtPnN0ciwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CgkJcCArPSBsZW47CgkJKnArKyA9ICc9JzsKCgkJLyogY2hlY2sgaWYgdGhlIHZhbHVlIGNvbnRhaW5zIHNwYWNlcyBhbmQgbWF5YmUgcXVvdGUgaXQgKi8KCQl2YWx1ZSsrOwoJCW5lZWRzX3F1b3RlID0gc3RyY2hyVyh2YWx1ZSwnICcpID8gMSA6IDA7CgkJaWYobmVlZHNfcXVvdGUpCgkJCSpwKysgPSAnIic7CgkJbGVuID0gbHN0cmxlblcodmFsdWUpOwoJCW1lbWNweShwLCB2YWx1ZSwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CgkJcCArPSBsZW47CgkJaWYobmVlZHNfcXVvdGUpCgkJCSpwKysgPSAnIic7Cgl9CgkqcCA9IDA7CgoJV0lORV9UUkFDRSgicHJvcGVydGllcyAtPiAlc1xuIiwgd2luZV9kYmdzdHJfdyhyZXQpICk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIExQV1NUUiBidWlsZF90cmFuc2Zvcm1zKHN0cnVjdCBzdHJpbmdfbGlzdCAqdHJhbnNmb3JtX2xpc3QpCnsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqbGlzdDsKCUxQV1NUUiByZXQsIHA7CglEV09SRCBsZW47CgoJLyogY291bnQgdGhlIHNwYWNlIHdlIG5lZWQgKi8KCWxlbiA9IDE7Cglmb3IobGlzdCA9IHRyYW5zZm9ybV9saXN0OyBsaXN0OyBsaXN0ID0gbGlzdC0+bmV4dCkKCQlsZW4gKz0gbHN0cmxlblcobGlzdC0+c3RyKSArIDE7CgoJcmV0ID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKFdDSEFSKSApOwoKCS8qIGFkZCBhbGwgdGhlIHRyYW5zZm9ybXMgd2l0aCBhIHNlbWljb2xvbiBiZXR3ZWVuIGVhY2ggb25lICovCglwID0gcmV0OwoJZm9yKGxpc3QgPSB0cmFuc2Zvcm1fbGlzdDsgbGlzdDsgbGlzdCA9IGxpc3QtPm5leHQpCgl7CgkJbGVuID0gbHN0cmxlblcobGlzdC0+c3RyKTsKCQlsc3RyY3B5blcocCwgbGlzdC0+c3RyLCBsZW4gKTsKCQlwICs9IGxlbjsKCQlpZihsaXN0LT5uZXh0KQoJCQkqcCsrID0gJzsnOwoJfQoJKnAgPSAwOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBEV09SRCBtc2lfYXRvdShMUENXU1RSIHN0cikKewoJRFdPUkQgcmV0ID0gMDsKCXdoaWxlKCpzdHIgPj0gJzAnICYmICpzdHIgPD0gJzknKQoJewoJCXJldCAqPSAxMDsKCQlyZXQgKz0gKCpzdHIgLSAnMCcpOwoJCXN0cisrOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBMUFdTVFIgbXNpX3N0cmR1cChMUENXU1RSIHN0cikKewoJRFdPUkQgbGVuID0gbHN0cmxlblcoc3RyKSsxOwoJTFBXU1RSIHJldCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpKmxlbik7Cglsc3RyY3B5VyhyZXQsIHN0cik7CglyZXR1cm4gcmV0Owp9CgovKiBzdHIxIGlzIHRoZSBzYW1lIGFzIHN0cjIsIGlnbm9yaW5nIGNhc2UgKi8Kc3RhdGljIEJPT0wgbXNpX3N0cmVxdWFsKExQQ1dTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKCURXT1JEIGxlbiwgcmV0OwoJTFBXU1RSIHN0clc7CgoJbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCBzdHIyLCAtMSwgTlVMTCwgMCk7CglpZiggIWxlbiApCgkJcmV0dXJuIEZBTFNFOwoJaWYoIGxzdHJsZW5XKHN0cjEpICE9IChsZW4tMSkgKQoJCXJldHVybiBGQUxTRTsKCXN0clcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSpsZW4pOwoJTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCBzdHIyLCAtMSwgc3RyVywgbGVuKTsKCXJldCA9IENvbXBhcmVTdHJpbmdXKEdldFRocmVhZExvY2FsZSgpLCBOT1JNX0lHTk9SRUNBU0UsIHN0cjEsIGxlbiwgc3RyVywgbGVuKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0clcpOwoJcmV0dXJuIChyZXQgPT0gQ1NUUl9FUVVBTCk7Cn0KCi8qIHByZWZpeCBpcyBoeXBoZW4gb3IgZGFzaCwgYW5kIHN0cjEgaXMgdGhlIHNhbWUgYXMgc3RyMiwgaWdub3JpbmcgY2FzZSAqLwpzdGF0aWMgQk9PTCBtc2lfb3B0aW9uX2VxdWFsKExQQ1dTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKICAgIGlmIChzdHIxWzBdICE9ICcvJyAmJiBzdHIxWzBdICE9ICctJykKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgLyogc2tpcCBvdmVyIHRoZSBoeXBoZW4gb3Igc2xhc2ggKi8KICAgIHJldHVybiBtc2lfc3RyZXF1YWwoc3RyMSArIDEsIHN0cjIpOwp9CgovKiBzdHIyIGlzIGF0IHRoZSBiZWdpbm5pbmcgb2Ygc3RyMSwgaWdub3JpbmcgY2FzZSAqLwpzdGF0aWMgQk9PTCBtc2lfc3RycHJlZml4KExQQ1dTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKCURXT1JEIGxlbiwgcmV0OwoJTFBXU1RSIHN0clc7CgoJbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCBzdHIyLCAtMSwgTlVMTCwgMCk7CglpZiggIWxlbiApCgkJcmV0dXJuIEZBTFNFOwoJaWYoIGxzdHJsZW5XKHN0cjEpIDwgKGxlbi0xKSApCgkJcmV0dXJuIEZBTFNFOwoJc3RyVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpKmxlbik7CglNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0cjIsIC0xLCBzdHJXLCBsZW4pOwoJcmV0ID0gQ29tcGFyZVN0cmluZ1coR2V0VGhyZWFkTG9jYWxlKCksIE5PUk1fSUdOT1JFQ0FTRSwgc3RyMSwgbGVuLTEsIHN0clcsIGxlbi0xKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0clcpOwoJcmV0dXJuIChyZXQgPT0gQ1NUUl9FUVVBTCk7Cn0KCi8qIHByZWZpeCBpcyBoeXBoZW4gb3IgZGFzaCwgYW5kIHN0cjIgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiBzdHIxLCBpZ25vcmluZyBjYXNlICovCnN0YXRpYyBCT09MIG1zaV9vcHRpb25fcHJlZml4KExQQ1dTVFIgc3RyMSwgTFBDU1RSIHN0cjIpCnsKICAgIGlmIChzdHIxWzBdICE9ICcvJyAmJiBzdHIxWzBdICE9ICctJykKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgLyogc2tpcCBvdmVyIHRoZSBoeXBoZW4gb3Igc2xhc2ggKi8KICAgIHJldHVybiBtc2lfc3RycHJlZml4KHN0cjEgKyAxLCBzdHIyKTsKfQoKc3RhdGljIFZPSUQgKkxvYWRQcm9jKExQQ1dTVFIgRGxsTmFtZSwgTFBDU1RSIFByb2NOYW1lLCBITU9EVUxFKiBEbGxIYW5kbGUpCnsKCVZPSUQqICgqcHJvYykodm9pZCk7CgoJKkRsbEhhbmRsZSA9IExvYWRMaWJyYXJ5RXhXKERsbE5hbWUsIE5VTEwsIExPQURfV0lUSF9BTFRFUkVEX1NFQVJDSF9QQVRIKTsKCWlmKCEqRGxsSGFuZGxlKQoJewoJCWZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvYWQgZGxsICVzXG4iLCB3aW5lX2RiZ3N0cl93KERsbE5hbWUpKTsKCQlFeGl0UHJvY2VzcygxKTsKCX0KCXByb2MgPSAoVk9JRCAqKSBHZXRQcm9jQWRkcmVzcygqRGxsSGFuZGxlLCBQcm9jTmFtZSk7CglpZighcHJvYykKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIkRsbCAlcyBkb2VzIG5vdCBpbXBsZW1lbnQgZnVuY3Rpb24gJXNcbiIsCgkJCXdpbmVfZGJnc3RyX3coRGxsTmFtZSksIFByb2NOYW1lKTsKCQlGcmVlTGlicmFyeSgqRGxsSGFuZGxlKTsKCQlFeGl0UHJvY2VzcygxKTsKCX0KCglyZXR1cm4gcHJvYzsKfQoKc3RhdGljIERXT1JEIERvRGxsUmVnaXN0ZXJTZXJ2ZXIoTFBDV1NUUiBEbGxOYW1lKQp7CglIUkVTVUxUIGhyOwoJRExMUkVHSVNURVJTRVJWRVIgcGZEbGxSZWdpc3RlclNlcnZlciA9IE5VTEw7CglITU9EVUxFIERsbEhhbmRsZSA9IE5VTEw7CgoJcGZEbGxSZWdpc3RlclNlcnZlciA9IExvYWRQcm9jKERsbE5hbWUsICJEbGxSZWdpc3RlclNlcnZlciIsICZEbGxIYW5kbGUpOwoKCWhyID0gcGZEbGxSZWdpc3RlclNlcnZlcigpOwoJaWYoRkFJTEVEKGhyKSkKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCB0byByZWdpc3RlciBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJCXJldHVybiAxOwoJfQoJcHJpbnRmKCJTdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJaWYoRGxsSGFuZGxlKQoJCUZyZWVMaWJyYXJ5KERsbEhhbmRsZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIERXT1JEIERvRGxsVW5yZWdpc3RlclNlcnZlcihMUENXU1RSIERsbE5hbWUpCnsKCUhSRVNVTFQgaHI7CglETExVTlJFR0lTVEVSU0VSVkVSIHBmRGxsVW5yZWdpc3RlclNlcnZlciA9IE5VTEw7CglITU9EVUxFIERsbEhhbmRsZSA9IE5VTEw7CgoJcGZEbGxVbnJlZ2lzdGVyU2VydmVyID0gTG9hZFByb2MoRGxsTmFtZSwgIkRsbFVucmVnaXN0ZXJTZXJ2ZXIiLCAmRGxsSGFuZGxlKTsKCglociA9IHBmRGxsVW5yZWdpc3RlclNlcnZlcigpOwoJaWYoRkFJTEVEKGhyKSkKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCB0byB1bnJlZ2lzdGVyIGRsbCAlc1xuIiwgd2luZV9kYmdzdHJfdyhEbGxOYW1lKSk7CgkJcmV0dXJuIDE7Cgl9CglwcmludGYoIlN1Y2Nlc3NmdWxseSB1bnJlZ2lzdGVyZWQgZGxsICVzXG4iLCB3aW5lX2RiZ3N0cl93KERsbE5hbWUpKTsKCWlmKERsbEhhbmRsZSkKCQlGcmVlTGlicmFyeShEbGxIYW5kbGUpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBEV09SRCBEb1JlZ1NlcnZlcih2b2lkKQp7CiAgICBTQ19IQU5ETEUgc2NtLCBzZXJ2aWNlOwogICAgQ0hBUiBwYXRoW01BWF9QQVRIKzEyXTsKICAgIERXT1JEIHJldCA9IDA7CgogICAgc2NtID0gT3BlblNDTWFuYWdlcihOVUxMLCBTRVJWSUNFU19BQ1RJVkVfREFUQUJBU0UsIFNDX01BTkFHRVJfQ1JFQVRFX1NFUlZJQ0UpOwogICAgaWYgKCFzY20pCiAgICB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICJGYWlsZWQgdG8gb3BlbiB0aGUgc2VydmljZSBjb250cm9sIG1hbmFnZXIuXG4iKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICBHZXRTeXN0ZW1EaXJlY3RvcnkocGF0aCwgTUFYX1BBVEgpOwogICAgbHN0cmNhdEEocGF0aCwgIlxcbXNpZXhlYy5leGUiKTsKCiAgICBzZXJ2aWNlID0gQ3JlYXRlU2VydmljZUEoc2NtLCAiTVNJU2VydmVyIiwgIk1TSVNlcnZlciIsIEdFTkVSSUNfQUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFUlZJQ0VfV0lOMzJfU0hBUkVfUFJPQ0VTUywgU0VSVklDRV9ERU1BTkRfU1RBUlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0VSVklDRV9FUlJPUl9OT1JNQUwsIHBhdGgsIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgTlVMTCk7CgogICAgaWYgKHNlcnZpY2UpIENsb3NlU2VydmljZUhhbmRsZShzZXJ2aWNlKTsKICAgIGVsc2UgaWYgKEdldExhc3RFcnJvcigpICE9IEVSUk9SX1NFUlZJQ0VfRVhJU1RTKQogICAgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiRmFpbGVkIHRvIGNyZWF0ZSBNU0kgc2VydmljZVxuIik7CiAgICAgICAgcmV0ID0gMTsKICAgIH0KICAgIENsb3NlU2VydmljZUhhbmRsZShzY20pOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIElOVCBEb0VtYmVkZGluZyggTFBXU1RSIGtleSApCnsKCXByaW50ZigiUmVtb3RlIGN1c3RvbSBhY3Rpb25zIGFyZSBub3Qgc3VwcG9ydGVkIHlldFxuIik7CglyZXR1cm4gMTsKfQoKLyoKICogc3RhdGUgbWFjaGluZSB0byBicmVhayB1cCB0aGUgY29tbWFuZCBsaW5lIHByb3Blcmx5CiAqLwoKZW51bSBjaG9tcF9zdGF0ZQp7Cgljc193aGl0ZXNwYWNlLAoJY3NfdG9rZW4sCgljc19xdW90ZQp9OwoKc3RhdGljIGludCBjaG9tcCggV0NIQVIgKnN0ciApCnsKCWVudW0gY2hvbXBfc3RhdGUgc3RhdGUgPSBjc193aGl0ZXNwYWNlOwoJV0NIQVIgKnAsICpvdXQ7CglpbnQgY291bnQgPSAwLCBpZ25vcmU7CgoJZm9yKCBwID0gc3RyLCBvdXQgPSBzdHI7ICpwOyBwKysgKQoJewoJCWlnbm9yZSA9IDE7CgkJc3dpdGNoKCBzdGF0ZSApCgkJewoJCWNhc2UgY3Nfd2hpdGVzcGFjZToKCQkJc3dpdGNoKCAqcCApCgkJCXsKCQkJY2FzZSAnICc6CgkJCQlicmVhazsKCQkJY2FzZSAnIic6CgkJCQlzdGF0ZSA9IGNzX3F1b3RlOwoJCQkJY291bnQrKzsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJY291bnQrKzsKCQkJCWlnbm9yZSA9IDA7CgkJCQlzdGF0ZSA9IGNzX3Rva2VuOwoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIGNzX3Rva2VuOgoJCQlzd2l0Y2goICpwICkKCQkJewoJCQljYXNlICciJzoKCQkJCXN0YXRlID0gY3NfcXVvdGU7CgkJCQlicmVhazsKCQkJY2FzZSAnICc6CgkJCQlzdGF0ZSA9IGNzX3doaXRlc3BhY2U7CgkJCQkqb3V0KysgPSAwOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlpZ25vcmUgPSAwOwoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIGNzX3F1b3RlOgoJCQlzd2l0Y2goICpwICkKCQkJewoJCQljYXNlICciJzoKCQkJCXN0YXRlID0gY3NfdG9rZW47CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWlnbm9yZSA9IDA7CgkJCX0KCQkJYnJlYWs7CgkJfQoJCWlmKCAhaWdub3JlICkKCQkJKm91dCsrID0gKnA7Cgl9CgoJKm91dCA9IDA7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgdm9pZCBwcm9jZXNzX2FyZ3MoIFdDSEFSICpjbWRsaW5lLCBpbnQgKnBhcmdjLCBXQ0hBUiAqKipwYXJndiApCnsKCVdDSEFSICoqYXJndiwgKnAgPSBtc2lfc3RyZHVwKGNtZGxpbmUpOwoJaW50IGksIG47CgoJbiA9IGNob21wKCBwICk7Cglhcmd2ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZiAoV0NIQVIqKSoobisxKSk7Cglmb3IoIGk9MDsgaTxuOyBpKysgKQoJewoJCWFyZ3ZbaV0gPSBwOwoJCXAgKz0gbHN0cmxlblcocCkgKyAxOwoJfQoJYXJndltpXSA9IE5VTEw7CgoJKnBhcmdjID0gbjsKCSpwYXJndiA9IGFyZ3Y7Cn0KCnN0YXRpYyBCT09MIHByb2Nlc3NfYXJnc19mcm9tX3JlZyggTFBXU1RSIGlkZW50LCBpbnQgKnBhcmdjLCBXQ0hBUiAqKipwYXJndiApCnsKCUxPTkcgcjsKCUhLRVkgaGtleSA9IDAsIGhrZXlBcmdzID0gMDsKCURXT1JEIHN6ID0gMCwgdHlwZSA9IDA7CglMUFdTVFIgYnVmID0gTlVMTDsKCUJPT0wgcmV0ID0gRkFMU0U7CgoJciA9IFJlZ09wZW5LZXlXKEhLRVlfTE9DQUxfTUFDSElORSwgSW5zdGFsbFJ1bk9uY2UsICZoa2V5KTsKCWlmKHIgIT0gRVJST1JfU1VDQ0VTUykKCQlyZXR1cm4gRkFMU0U7CglyID0gUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBpZGVudCwgMCwgJnR5cGUsIDAsICZzeik7CglpZihyID09IEVSUk9SX1NVQ0NFU1MgJiYgdHlwZSA9PSBSRUdfU1opCgl7CgkJYnVmID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN6KTsKCQlyID0gUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBpZGVudCwgMCwgJnR5cGUsIChMUEJZVEUpYnVmLCAmc3opOwoJCWlmKCByID09IEVSUk9SX1NVQ0NFU1MgKQoJCXsKCQkJcHJvY2Vzc19hcmdzKGJ1ZiwgcGFyZ2MsIHBhcmd2KTsKCQkJcmV0ID0gVFJVRTsKCQl9Cgl9CglSZWdDbG9zZUtleShoa2V5QXJncyk7CglyZXR1cm4gcmV0Owp9CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKCWludCBpOwoJQk9PTCBGdW5jdGlvbkluc3RhbGwgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25JbnN0YWxsQWRtaW4gPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25SZXBhaXIgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25BZHZlcnRpc2UgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25QYXRjaCA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvbkRsbFJlZ2lzdGVyU2VydmVyID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uRGxsVW5yZWdpc3RlclNlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvblJlZ1NlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvblVucmVnU2VydmVyID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uVW5rbm93biA9IEZBTFNFOwoKCUxQV1NUUiBQYWNrYWdlTmFtZSA9IE5VTEw7CglMUFdTVFIgUHJvcGVydGllcyA9IE5VTEw7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKnByb3BlcnR5X2xpc3QgPSBOVUxMOwoKCURXT1JEIFJlcGFpck1vZGUgPSAwOwoKCURXT1JEX1BUUiBBZHZlcnRpc2VNb2RlID0gMDsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqdHJhbnNmb3JtX2xpc3QgPSBOVUxMOwoJTEFOR0lEIExhbmd1YWdlID0gMDsKCglEV09SRCBMb2dNb2RlID0gMDsKCUxQV1NUUiBMb2dGaWxlTmFtZSA9IE5VTEw7CglEV09SRCBMb2dBdHRyaWJ1dGVzID0gMDsKCglMUFdTVFIgUGF0Y2hGaWxlTmFtZSA9IE5VTEw7CglJTlNUQUxMVFlQRSBJbnN0YWxsVHlwZSA9IElOU1RBTExUWVBFX0RFRkFVTFQ7CgoJSU5TVEFMTFVJTEVWRUwgSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9GVUxMOwoKCUxQV1NUUiBEbGxOYW1lID0gTlVMTDsKCURXT1JEIFJldHVybkNvZGU7CglMUFdTVFIgKmFyZ3ZXID0gTlVMTDsKCgkvKiBvdmVyd3JpdGUgdGhlIGNvbW1hbmQgbGluZSAqLwoJcHJvY2Vzc19hcmdzKCBHZXRDb21tYW5kTGluZVcoKSwgJmFyZ2MsICZhcmd2VyApOwoKCS8qCgkgKiBJZiB0aGUgYXJncyBiZWdpbiB3aXRoIC9AIElERU5UIHRoZW4gd2UgbmVlZCB0byBsb2FkIHRoZSByZWFsCgkgKiBjb21tYW5kIGxpbmUgb3V0IG9mIHRoZSBSdW5PbmNlRW50cmllcyBrZXkgaW4gdGhlIHJlZ2lzdHJ5LgoJICogIFdlIGRvIHRoYXQgYmVmb3JlIHN0YXJ0aW5nIHRvIHByb2Nlc3MgdGhlIHJlYWwgY29tbWFuZGxpbmUsCgkgKiB0aGVuIG92ZXJ3cml0ZSB0aGUgY29tbWFuZGxpbmUgYWdhaW4uCgkgKi8KCWlmKGFyZ2M+MSAmJiBtc2lfb3B0aW9uX2VxdWFsKGFyZ3ZXWzFdLCAiQCIpKQoJewoJCWlmKCFwcm9jZXNzX2FyZ3NfZnJvbV9yZWcoIGFyZ3ZXWzJdLCAmYXJnYywgJmFyZ3ZXICkpCgkJCXJldHVybiAxOwoJfQoKCWlmIChhcmdjID09IDMgJiYgbXNpX29wdGlvbl9lcXVhbChhcmd2V1sxXSwgIkVtYmVkZGluZyIpKQoJCXJldHVybiBEb0VtYmVkZGluZyggYXJndldbMl0gKTsKCglmb3IoaSA9IDE7IGkgPCBhcmdjOyBpKyspCgl7CgkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCgkJaWYgKG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICJyZWdzZXJ2ZXIiKSkKCQl7CgkJCUZ1bmN0aW9uUmVnU2VydmVyID0gVFJVRTsKCQl9CgkJZWxzZSBpZiAobXNpX29wdGlvbl9lcXVhbChhcmd2V1tpXSwgInVucmVnc2VydmVyIikgfHwgbXNpX29wdGlvbl9lcXVhbChhcmd2V1tpXSwgInVucmVnaXN0ZXIiKSkKCQl7CgkJCUZ1bmN0aW9uVW5yZWdTZXJ2ZXIgPSBUUlVFOwoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fcHJlZml4KGFyZ3ZXW2ldLCAiaSIpKQoJCXsKCQkJTFBXU1RSIGFyZ3ZXaSA9IGFyZ3ZXW2ldOwoJCQlGdW5jdGlvbkluc3RhbGwgPSBUUlVFOwoJCQlpZihsc3RybGVuVyhhcmd2V2kpID4gMikKCQkJCWFyZ3ZXaSArPSAyOwoJCQllbHNlCgkJCXsKCQkJCWkrKzsKCQkJCWlmKGkgPj0gYXJnYykKCQkJCQlTaG93VXNhZ2UoMSk7CgkJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQkJYXJndldpID0gYXJndldbaV07CgkJCX0KCQkJUGFja2FnZU5hbWUgPSBhcmd2V2k7CgkJfQoJCWVsc2UgaWYobXNpX29wdGlvbl9lcXVhbChhcmd2V1tpXSwgImEiKSkKCQl7CgkJCUZ1bmN0aW9uSW5zdGFsbCA9IFRSVUU7CgkJCUZ1bmN0aW9uSW5zdGFsbEFkbWluID0gVFJVRTsKCQkJSW5zdGFsbFR5cGUgPSBJTlNUQUxMVFlQRV9ORVRXT1JLX0lNQUdFOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXTsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmcHJvcGVydHlfbGlzdCwgQWN0aW9uQWRtaW4pOwoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fcHJlZml4KGFyZ3ZXW2ldLCAiZiIpKQoJCXsKCQkJaW50IGo7CgkJCWludCBsZW4gPSBsc3RybGVuVyhhcmd2V1tpXSk7CgkJCUZ1bmN0aW9uUmVwYWlyID0gVFJVRTsKCQkJZm9yKGogPSAyOyBqIDwgbGVuOyBqKyspCgkJCXsKCQkJCXN3aXRjaChhcmd2V1tpXVtqXSkKCQkJCXsKCQkJCQljYXNlICdQJzoKCQkJCQljYXNlICdwJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVNSVNTSU5HOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdPJzoKCQkJCQljYXNlICdvJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVPTERFUlZFUlNJT047CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0UnOgoJCQkJCWNhc2UgJ2UnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRUVRVUFMVkVSU0lPTjsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnRCc6CgkJCQkJY2FzZSAnZCc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFRVhBQ1Q7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0MnOgoJCQkJCWNhc2UgJ2MnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRVZFUklGWTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnQSc6CgkJCQkJY2FzZSAnYSc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFUkVQTEFDRTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVSc6CgkJCQkJY2FzZSAndSc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9VU0VSREFUQTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnTSc6CgkJCQkJY2FzZSAnbSc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9NQUNISU5FREFUQTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnUyc6CgkJCQkJY2FzZSAncyc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9TSE9SVENVVDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVic6CgkJCQkJY2FzZSAndic6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9QQUNLQUdFOwoJCQkJCQlicmVhazsKCQkJCQlkZWZhdWx0OgoJCQkJCQlmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gb3B0aW9uIFwiJWNcIiBpbiBSZXBhaXIgbW9kZVxuIiwgYXJndldbaV1bal0pOwoJCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQlpZihsZW4gPT0gMikKCQkJewoJCQkJUmVwYWlyTW9kZSA9IFJFSU5TVEFMTE1PREVfRklMRU1JU1NJTkcgfAoJCQkJCVJFSU5TVEFMTE1PREVfRklMRUVRVUFMVkVSU0lPTiB8CgkJCQkJUkVJTlNUQUxMTU9ERV9GSUxFVkVSSUZZIHwKCQkJCQlSRUlOU1RBTExNT0RFX01BQ0hJTkVEQVRBIHwKCQkJCQlSRUlOU1RBTExNT0RFX1NIT1JUQ1VUOwoJCQl9CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fcHJlZml4KGFyZ3ZXW2ldLCAieCIpKQoJCXsKCQkJRnVuY3Rpb25JbnN0YWxsID0gVFJVRTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXSsyOwoJCQlpZiAoIVBhY2thZ2VOYW1lWzBdKQoJCQl7CgkJCQlpKys7CgkJCQlpZiAoaSA+PSBhcmdjKQoJCQkJCVNob3dVc2FnZSgxKTsKCQkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJCX0KCQkJV0lORV9UUkFDRSgiUGFja2FnZU5hbWUgPSAlc1xuIiwgd2luZV9kYmdzdHJfdyhQYWNrYWdlTmFtZSkpOwoJCQlTdHJpbmdMaXN0QXBwZW5kKCZwcm9wZXJ0eV9saXN0LCBSZW1vdmVBbGwpOwoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fcHJlZml4KGFyZ3ZXW2ldLCAiaiIpKQoJCXsKCQkJaW50IGo7CgkJCWludCBsZW4gPSBsc3RybGVuVyhhcmd2V1tpXSk7CgkJCUZ1bmN0aW9uQWR2ZXJ0aXNlID0gVFJVRTsKCQkJZm9yKGogPSAyOyBqIDwgbGVuOyBqKyspCgkJCXsKCQkJCXN3aXRjaChhcmd2V1tpXVtqXSkKCQkJCXsKCQkJCQljYXNlICdVJzoKCQkJCQljYXNlICd1JzoKCQkJCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX1VTRVJBU1NJR047CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ00nOgoJCQkJCWNhc2UgJ20nOgoJCQkJCQlBZHZlcnRpc2VNb2RlID0gQURWRVJUSVNFRkxBR1NfTUFDSElORUFTU0lHTjsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIG9wdGlvbiBcIiVjXCIgaW4gQWR2ZXJ0aXNlIG1vZGVcbiIsIGFyZ3ZXW2ldW2pdKTsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYobXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAidSIpKQoJCXsKCQkJRnVuY3Rpb25BZHZlcnRpc2UgPSBUUlVFOwoJCQlBZHZlcnRpc2VNb2RlID0gQURWRVJUSVNFRkxBR1NfVVNFUkFTU0lHTjsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYobXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAibSIpKQoJCXsKCQkJRnVuY3Rpb25BZHZlcnRpc2UgPSBUUlVFOwoJCQlBZHZlcnRpc2VNb2RlID0gQURWRVJUSVNFRkxBR1NfTUFDSElORUFTU0lHTjsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYobXNpX29wdGlvbl9lcXVhbChhcmd2V1tpXSwgInQiKSkKCQl7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlTdHJpbmdMaXN0QXBwZW5kKCZ0cmFuc2Zvcm1fbGlzdCwgYXJndldbaV0pOwoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICJnIikpCgkJewoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJTGFuZ3VhZ2UgPSBtc2lfYXRvdShhcmd2V1tpXSk7CgkJfQoJCWVsc2UgaWYobXNpX29wdGlvbl9wcmVmaXgoYXJndldbaV0sICJsIikpCgkJewoJCQlpbnQgajsKCQkJaW50IGxlbiA9IGxzdHJsZW5XKGFyZ3ZXW2ldKTsKCQkJZm9yKGogPSAyOyBqIDwgbGVuOyBqKyspCgkJCXsKCQkJCXN3aXRjaChhcmd2V1tpXVtqXSkKCQkJCXsKCQkJCQljYXNlICdJJzoKCQkJCQljYXNlICdpJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9JTkZPOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdXJzoKCQkJCQljYXNlICd3JzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9XQVJOSU5HOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdFJzoKCQkJCQljYXNlICdlJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9FUlJPUjsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnQSc6CgkJCQkJY2FzZSAnYSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfQUNUSU9OU1RBUlQ7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1InOgoJCQkJCWNhc2UgJ3InOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0FDVElPTkRBVEE7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1UnOgoJCQkJCWNhc2UgJ3UnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX1VTRVI7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0MnOgoJCQkJCWNhc2UgJ2MnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0NPTU1PTkRBVEE7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ00nOgoJCQkJCWNhc2UgJ20nOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0ZBVEFMRVhJVDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnTyc6CgkJCQkJY2FzZSAnbyc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfT1VUT0ZESVNLU1BBQ0U7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1AnOgoJCQkJCWNhc2UgJ3AnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX1BST1BFUlRZRFVNUDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVic6CgkJCQkJY2FzZSAndic6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfVkVSQk9TRTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnKic6CgkJCQkJCUxvZ01vZGUgPSBJTlNUQUxMTE9HTU9ERV9GQVRBTEVYSVQgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfRVJST1IgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfV0FSTklORyB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9VU0VSIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0lORk8gfAoJCQkJCQkJSU5TVEFMTExPR01PREVfUkVTT0xWRVNPVVJDRSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9PVVRPRkRJU0tTUEFDRSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9BQ1RJT05TVEFSVCB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9BQ1RJT05EQVRBIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0NPTU1PTkRBVEEgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfUFJPUEVSVFlEVU1QIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1BST0dSRVNTIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0lOSVRJQUxJWkUgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfVEVSTUlOQVRFIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1NIT1dESUFMT0c7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJysnOgoJCQkJCQlMb2dBdHRyaWJ1dGVzIHw9IElOU1RBTExMT0dBVFRSSUJVVEVTX0FQUEVORDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnISc6CgkJCQkJCUxvZ0F0dHJpYnV0ZXMgfD0gSU5TVEFMTExPR0FUVFJJQlVURVNfRkxVU0hFQUNITElORTsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCUxvZ0ZpbGVOYW1lID0gYXJndldbaV07CgkJCWlmKE1zaUVuYWJsZUxvZ1coTG9nTW9kZSwgTG9nRmlsZU5hbWUsIExvZ0F0dHJpYnV0ZXMpICE9IEVSUk9SX1NVQ0NFU1MpCgkJCXsKCQkJCWZwcmludGYoc3RkZXJyLCAiTG9nZ2luZyBpbiAlcyAoMHglMDh4LCAldSkgZmFpbGVkXG4iLAoJCQkJCSB3aW5lX2RiZ3N0cl93KExvZ0ZpbGVOYW1lKSwgTG9nTW9kZSwgTG9nQXR0cmlidXRlcyk7CgkJCQlFeGl0UHJvY2VzcygxKTsKCQkJfQoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICJwIikpCgkJewoJCQlGdW5jdGlvblBhdGNoID0gVFJVRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhdGNoRmlsZU5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX3ByZWZpeChhcmd2V1tpXSwgInEiKSkKCQl7CgkJCWlmKGxzdHJsZW5XKGFyZ3ZXW2ldKSA9PSAyIHx8IG1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAibiIpIHx8CgkJCSAgIG1zaV9zdHJlcXVhbChhcmd2V1tpXSArIDIsICJ1aWV0IikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfTk9ORTsKCQkJfQoJCQllbHNlIGlmKG1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiYiIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0JBU0lDOwoJCQl9CgkJCWVsc2UgaWYobXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJyIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfUkVEVUNFRDsKCQkJfQoJCQllbHNlIGlmKG1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiZiIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0ZVTEx8SU5TVEFMTFVJTEVWRUxfRU5ERElBTE9HOwoJCQl9CgkJCWVsc2UgaWYobXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJuKyIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX05PTkV8SU5TVEFMTFVJTEVWRUxfRU5ERElBTE9HOwoJCQl9CgkJCWVsc2UgaWYobXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJiKyIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0JBU0lDfElOU1RBTExVSUxFVkVMX0VORERJQUxPRzsKCQkJfQoJCQllbHNlIGlmKG1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiYi0iKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9CQVNJQ3xJTlNUQUxMVUlMRVZFTF9QUk9HUkVTU09OTFk7CgkJCX0KCQkJZWxzZSBpZihtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgImIrISIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0JBU0lDfElOU1RBTExVSUxFVkVMX0VORERJQUxPRzsKCQkJCVdJTkVfRklYTUUoIlVua25vd24gbW9kaWZpZXI6ICFcbiIpOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIG9wdGlvbiBcIiVzXCIgZm9yIFVJIGxldmVsXG4iLAoJCQkJCSB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKzIpKTsKCQkJfQoJCX0KCQllbHNlIGlmKG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICJ5IikpCgkJewoJCQlGdW5jdGlvbkRsbFJlZ2lzdGVyU2VydmVyID0gVFJVRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCURsbE5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX2VxdWFsKGFyZ3ZXW2ldLCAieiIpKQoJCXsKCQkJRnVuY3Rpb25EbGxVbnJlZ2lzdGVyU2VydmVyID0gVFJVRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCURsbE5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX2VxdWFsKGFyZ3ZXW2ldLCAiaCIpIHx8IG1zaV9vcHRpb25fZXF1YWwoYXJndldbaV0sICI/IikpCgkJewoJCQlTaG93VXNhZ2UoMCk7CgkJfQoJCWVsc2UgaWYobXNpX29wdGlvbl9lcXVhbChhcmd2V1tpXSwgIm0iKSkKCQl7CgkJCUZ1bmN0aW9uVW5rbm93biA9IFRSVUU7CgkJCVdJTkVfRklYTUUoIlVua25vd24gcGFyYW1ldGVyIC9tXG4iKTsKCQl9CgkJZWxzZSBpZihtc2lfb3B0aW9uX2VxdWFsKGFyZ3ZXW2ldLCAiRCIpKQoJCXsKCQkJRnVuY3Rpb25Vbmtub3duID0gVFJVRTsKCQkJV0lORV9GSVhNRSgiVW5rbm93biBwYXJhbWV0ZXIgL0RcbiIpOwoJCX0KCQllbHNlCgkJCVN0cmluZ0xpc3RBcHBlbmQoJnByb3BlcnR5X2xpc3QsIGFyZ3ZXW2ldKTsKCX0KCgkvKiBzdGFydCB0aGUgR1VJICovCglNc2lTZXRJbnRlcm5hbFVJKEluc3RhbGxVSUxldmVsLCBOVUxMKTsKCglQcm9wZXJ0aWVzID0gYnVpbGRfcHJvcGVydGllcyggcHJvcGVydHlfbGlzdCApOwoKCWlmKEZ1bmN0aW9uSW5zdGFsbEFkbWluICYmIEZ1bmN0aW9uUGF0Y2gpCgkJRnVuY3Rpb25JbnN0YWxsID0gRkFMU0U7CgoJUmV0dXJuQ29kZSA9IDE7CglpZihGdW5jdGlvbkluc3RhbGwpCgl7CgkJaWYoSXNQcm9kdWN0Q29kZShQYWNrYWdlTmFtZSkpCgkJCVJldHVybkNvZGUgPSBNc2lDb25maWd1cmVQcm9kdWN0RXhXKFBhY2thZ2VOYW1lLCAwLCBJTlNUQUxMU1RBVEVfREVGQVVMVCwgUHJvcGVydGllcyk7CgkJZWxzZQoJCQlSZXR1cm5Db2RlID0gTXNpSW5zdGFsbFByb2R1Y3RXKFBhY2thZ2VOYW1lLCBQcm9wZXJ0aWVzKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25SZXBhaXIpCgl7CgkJaWYoSXNQcm9kdWN0Q29kZShQYWNrYWdlTmFtZSkpCgkJCVdJTkVfRklYTUUoIlByb2R1Y3QgY29kZSB0cmVhdG1lbnQgbm90IGltcGxlbWVudGVkIHlldFxuIik7CgkJZWxzZQoJCQlSZXR1cm5Db2RlID0gTXNpUmVpbnN0YWxsUHJvZHVjdFcoUGFja2FnZU5hbWUsIFJlcGFpck1vZGUpOwoJfQoJZWxzZSBpZihGdW5jdGlvbkFkdmVydGlzZSkKCXsKCQlMUFdTVFIgVHJhbnNmb3JtcyA9IGJ1aWxkX3RyYW5zZm9ybXMoIHByb3BlcnR5X2xpc3QgKTsKCQlSZXR1cm5Db2RlID0gTXNpQWR2ZXJ0aXNlUHJvZHVjdFcoUGFja2FnZU5hbWUsIChMUFdTVFIpIEFkdmVydGlzZU1vZGUsIFRyYW5zZm9ybXMsIExhbmd1YWdlKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25QYXRjaCkKCXsKCQlSZXR1cm5Db2RlID0gTXNpQXBwbHlQYXRjaFcoUGF0Y2hGaWxlTmFtZSwgUGFja2FnZU5hbWUsIEluc3RhbGxUeXBlLCBQcm9wZXJ0aWVzKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25EbGxSZWdpc3RlclNlcnZlcikKCXsKCQlSZXR1cm5Db2RlID0gRG9EbGxSZWdpc3RlclNlcnZlcihEbGxOYW1lKTsKCX0KCWVsc2UgaWYoRnVuY3Rpb25EbGxVbnJlZ2lzdGVyU2VydmVyKQoJewoJCVJldHVybkNvZGUgPSBEb0RsbFVucmVnaXN0ZXJTZXJ2ZXIoRGxsTmFtZSk7Cgl9CgllbHNlIGlmIChGdW5jdGlvblJlZ1NlcnZlcikKCXsKCQlSZXR1cm5Db2RlID0gRG9SZWdTZXJ2ZXIoKTsKCX0KCWVsc2UgaWYgKEZ1bmN0aW9uVW5yZWdTZXJ2ZXIpCgl7CgkJV0lORV9GSVhNRSggIi91bnJlZ3NlcnZlciBub3QgaW1wbGVtZW50ZWQgeWV0LCBpZ25vcmluZ1xuIiApOwoJfQoJZWxzZSBpZiAoRnVuY3Rpb25Vbmtub3duKQoJewoJCVdJTkVfRklYTUUoICJVbmtub3duIGZ1bmN0aW9uLCBpZ25vcmluZ1xuIiApOwoJfQoJZWxzZQoJCVNob3dVc2FnZSgxKTsKCglyZXR1cm4gUmV0dXJuQ29kZTsKfQo=