LyoKICogbXNpZXhlYy5leGUgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDQgVmluY2VudCBC6XJvbgogKiBDb3B5cmlnaHQgMjAwNSBNaWtlIE1jQ29ybWFjawogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8d2luZG93cy5oPgojaW5jbHVkZSA8bXNpLmg+CiNpbmNsdWRlIDxvYmpiYXNlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobXNpZXhlYyk7Cgp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqRExMUkVHSVNURVJTRVJWRVIpKHZvaWQpOwp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqRExMVU5SRUdJU1RFUlNFUlZFUikodm9pZCk7CgpzdHJ1Y3Qgc3RyaW5nX2xpc3QKewoJc3RydWN0IHN0cmluZ19saXN0ICpuZXh0OwoJV0NIQVIgc3RyWzFdOwp9OwoKc3RhdGljIGNvbnN0IGNoYXIgVXNhZ2VTdHJbXSA9CiJVc2FnZTpcbiIKIiAgSW5zdGFsbCBhIHByb2R1Y3Q6XG4iCiIgICAgbXNpZXhlYyB7cGFja2FnZXxwcm9kdWN0Y29kZX0gW3Byb3BlcnR5XVxuIgoiICAgIG1zaWV4ZWMgL2kge3BhY2thZ2V8cHJvZHVjdGNvZGV9IFtwcm9wZXJ0eV1cbiIKIiAgICBtc2lleGVjIC9hIHBhY2thZ2UgW3Byb3BlcnR5XVxuIgoiICBSZXBhaXIgYW4gaW5zdGFsbGF0aW9uOlxuIgoiICAgIG1zaWV4ZWMgL2ZbcHxvfGV8ZHxjfGF8dXxtfHN8dl0ge3BhY2thZ2V8cHJvZHVjdGNvZGV9XG4iCiIgIFVuaW5zdGFsbCBhIHByb2R1Y3Q6XG4iCiIgICAgbXNpZXhlYyAveCB7cGFja2FnZXxwcm9kdWN0Y29kZX0gW3Byb3BlcnR5XVxuIgoiICBBZHZlcnRpc2UgYSBwcm9kdWN0OlxuIgoiICAgIG1zaWV4ZWMgL2pbdXxtXSBwYWNrYWdlIFsvdCB0cmFuc2Zvcm1dIFsvZyBsYW5ndWFnZWlkXVxuIgoiICAgIG1zaWV4ZWMge3V8bX0gcGFja2FnZSBbL3QgdHJhbnNmb3JtXSBbL2cgbGFuZ3VhZ2VpZF1cbiIKIiAgQXBwbHkgYSBwYXRjaDpcbiIKIiAgICBtc2lleGVjIC9wIHBhdGNocGFja2FnZSBbcHJvcGVydHldXG4iCiIgICAgbXNpZXhlYyAvcCBwYXRjaHBhY2thZ2UgL2EgcGFja2FnZSBbcHJvcGVydHldXG4iCiIgIE1vZGlmaWVycyBmb3IgYWJvdmUgb3BlcmF0aW9uczpcbiIKIiAgICBtc2lleGVjIC9sWypdW2l8d3xlfGF8cnx1fGN8bXxvfHB8dnxdWyt8IV0gbG9nZmlsZVxuIgoiICAgIG1zaWV4ZWMgL3F7fG58YnxyfGZ8bit8Yit8Yi19XG4iCiIgIFJlZ2lzdGVyIGEgbW9kdWxlOlxuIgoiICAgIG1zaWV4ZWMgL3kgbW9kdWxlXG4iCiIgIFVucmVnaXN0ZXIgYSBtb2R1bGU6XG4iCiIgICAgbXNpZXhlYyAveiBtb2R1bGVcbiIKIiAgRGlzcGxheSB1c2FnZSBhbmQgY29weXJpZ2h0OlxuIgoiICAgIG1zaWV4ZWMgey9ofC8/fVxuIgoiTk9URTogUHJvZHVjdCBjb2RlIG9uIGNvbW1hbmRsaW5lIHVuaW1wbGVtZW50ZWQgYXMgb2YgeWV0XG4iCiJcbiIKIkNvcHlyaWdodCAyMDA0IFZpbmNlbnQgQulyb25cbiI7CgpzdGF0aWMgY29uc3QgV0NIQVIgQWN0aW9uQWRtaW5bXSA9IHsKICAgJ0EnLCdDJywnVCcsJ0knLCdPJywnTicsJz0nLCdBJywnRCcsJ00nLCdJJywnTicsMCB9OwpzdGF0aWMgY29uc3QgV0NIQVIgUmVtb3ZlQWxsW10gPSB7CiAgICdSJywnRScsJ00nLCdPJywnVicsJ0UnLCc9JywnQScsJ0wnLCdMJywwIH07CgpzdGF0aWMgY29uc3QgV0NIQVIgSW5zdGFsbFJ1bk9uY2VbXSA9IHsKICAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLAogICAnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1xcJywKICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXFwnLAogICAnSScsJ24nLCdzJywndCcsJ2EnLCdsJywnbCcsJ2UnLCdyJywnXFwnLAogICAnUicsJ3UnLCduJywnTycsJ24nLCdjJywnZScsJ0UnLCduJywndCcsJ3InLCdpJywnZScsJ3MnLDB9OwoKc3RhdGljIHZvaWQgU2hvd1VzYWdlKGludCBFeGl0Q29kZSkKewoJcHJpbnRmKFVzYWdlU3RyKTsKCUV4aXRQcm9jZXNzKEV4aXRDb2RlKTsKfQoKc3RhdGljIEJPT0wgSXNQcm9kdWN0Q29kZShMUFdTVFIgc3RyKQp7CglHVUlEIFByb2R1Y3RDb2RlOwoKCWlmKGxzdHJsZW5XKHN0cikgIT0gMzgpCgkJcmV0dXJuIEZBTFNFOwoJcmV0dXJuICggKENMU0lERnJvbVN0cmluZyhzdHIsICZQcm9kdWN0Q29kZSkgPT0gTk9FUlJPUikgKTsKCn0KCnN0YXRpYyBWT0lEIFN0cmluZ0xpc3RBcHBlbmQoc3RydWN0IHN0cmluZ19saXN0ICoqbGlzdCwgTFBDV1NUUiBzdHIpCnsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqZW50cnk7CglEV09SRCBzaXplOwoKCXNpemUgPSBzaXplb2YgKmVudHJ5ICsgbHN0cmxlblcoc3RyKSAqIHNpemVvZiAoV0NIQVIpOwoJZW50cnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CglpZighZW50cnkpCgl7CgkJV0lORV9FUlIoIk91dCBvZiBtZW1vcnkhXG4iKTsKCQlFeGl0UHJvY2VzcygxKTsKCX0KCWxzdHJjcHlXKGVudHJ5LT5zdHIsIHN0cik7CgllbnRyeS0+bmV4dCA9IE5VTEw7CgoJLyoKCSAqIElnbm9yaW5nIG8obl4yKSB0aW1lIGNvbXBsZXhpdHkgdG8gYWRkIG4gc3RyaW5ncyBmb3Igc2ltcGxpY2l0eSwKCSAqICBhZGQgdGhlIHN0cmluZyB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IHRvIHByZXNlcnZlIHRoZSBvcmRlci4KCSAqLwoJd2hpbGUoICpsaXN0ICkKCQlsaXN0ID0gJigqbGlzdCktPm5leHQ7CgkqbGlzdCA9IGVudHJ5Owp9CgpzdGF0aWMgTFBXU1RSIGJ1aWxkX3Byb3BlcnRpZXMoc3RydWN0IHN0cmluZ19saXN0ICpwcm9wZXJ0eV9saXN0KQp7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKmxpc3Q7CglMUFdTVFIgcmV0LCBwLCB2YWx1ZTsKCURXT1JEIGxlbjsKCUJPT0wgbmVlZHNfcXVvdGU7CgoJaWYoIXByb3BlcnR5X2xpc3QpCgkJcmV0dXJuIE5VTEw7CgoJLyogY291bnQgdGhlIHNwYWNlIHdlIG5lZWQgKi8KCWxlbiA9IDE7Cglmb3IobGlzdCA9IHByb3BlcnR5X2xpc3Q7IGxpc3Q7IGxpc3QgPSBsaXN0LT5uZXh0KQoJCWxlbiArPSBsc3RybGVuVyhsaXN0LT5zdHIpICsgMzsKCglyZXQgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbipzaXplb2YoV0NIQVIpICk7CgoJLyogYWRkIGEgc3BhY2UgYmVmb3JlIGVhY2ggc3RyaW5nLCBhbmQgcXVvdGUgdGhlIHZhbHVlICovCglwID0gcmV0OwoJZm9yKGxpc3QgPSBwcm9wZXJ0eV9saXN0OyBsaXN0OyBsaXN0ID0gbGlzdC0+bmV4dCkKCXsKCQl2YWx1ZSA9IHN0cmNoclcobGlzdC0+c3RyLCc9Jyk7CgkJaWYoIXZhbHVlKQoJCQljb250aW51ZTsKCQlsZW4gPSB2YWx1ZSAtIGxpc3QtPnN0cjsKCQkqcCsrID0gJyAnOwoJCW1lbWNweShwLCBsaXN0LT5zdHIsIGxlbiAqIHNpemVvZihXQ0hBUikpOwoJCXAgKz0gbGVuOwoJCSpwKysgPSAnPSc7CgoJCS8qIGNoZWNrIGlmIHRoZSB2YWx1ZSBjb250YWlucyBzcGFjZXMgYW5kIG1heWJlIHF1b3RlIGl0ICovCgkJdmFsdWUrKzsKCQluZWVkc19xdW90ZSA9IHN0cmNoclcodmFsdWUsJyAnKSA/IDEgOiAwOwoJCWlmKG5lZWRzX3F1b3RlKQoJCQkqcCsrID0gJyInOwoJCWxlbiA9IGxzdHJsZW5XKHZhbHVlKTsKCQltZW1jcHkocCwgdmFsdWUsIGxlbiAqIHNpemVvZihXQ0hBUikpOwoJCXAgKz0gbGVuOwoJCWlmKG5lZWRzX3F1b3RlKQoJCQkqcCsrID0gJyInOwoJfQoJKnAgPSAwOwoKCVdJTkVfVFJBQ0UoInByb3BlcnRpZXMgLT4gJXNcbiIsIHdpbmVfZGJnc3RyX3cocmV0KSApOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBMUFdTVFIgYnVpbGRfdHJhbnNmb3JtcyhzdHJ1Y3Qgc3RyaW5nX2xpc3QgKnRyYW5zZm9ybV9saXN0KQp7CglzdHJ1Y3Qgc3RyaW5nX2xpc3QgKmxpc3Q7CglMUFdTVFIgcmV0LCBwOwoJRFdPUkQgbGVuOwoKCS8qIGNvdW50IHRoZSBzcGFjZSB3ZSBuZWVkICovCglsZW4gPSAxOwoJZm9yKGxpc3QgPSB0cmFuc2Zvcm1fbGlzdDsgbGlzdDsgbGlzdCA9IGxpc3QtPm5leHQpCgkJbGVuICs9IGxzdHJsZW5XKGxpc3QtPnN0cikgKyAxOwoKCXJldCA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikgKTsKCgkvKiBhZGQgYWxsIHRoZSB0cmFuc2Zvcm1zIHdpdGggYSBzZW1pY29sb24gYmV0d2VlbiBlYWNoIG9uZSAqLwoJcCA9IHJldDsKCWZvcihsaXN0ID0gdHJhbnNmb3JtX2xpc3Q7IGxpc3Q7IGxpc3QgPSBsaXN0LT5uZXh0KQoJewoJCWxlbiA9IGxzdHJsZW5XKGxpc3QtPnN0cik7CgkJbHN0cmNweW5XKHAsIGxpc3QtPnN0ciwgbGVuICk7CgkJcCArPSBsZW47CgkJaWYobGlzdC0+bmV4dCkKCQkJKnArKyA9ICc7JzsKCX0KCSpwID0gMDsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgRFdPUkQgbXNpX2F0b3UoTFBDV1NUUiBzdHIpCnsKCURXT1JEIHJldCA9IDA7Cgl3aGlsZSgqc3RyID49ICcwJyAmJiAqc3RyIDw9ICc5JykKCXsKCQlyZXQgKj0gMTA7CgkJcmV0ICs9ICgqc3RyIC0gJzAnKTsKCQlzdHIrKzsKCX0KCXJldHVybiAwOwp9CgpzdGF0aWMgTFBXU1RSIG1zaV9zdHJkdXAoTFBDV1NUUiBzdHIpCnsKCURXT1JEIGxlbiA9IGxzdHJsZW5XKHN0cikrMTsKCUxQV1NUUiByZXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSpsZW4pOwoJbHN0cmNweVcocmV0LCBzdHIpOwoJcmV0dXJuIHJldDsKfQoKLyogc3RyMSBpcyB0aGUgc2FtZSBhcyBzdHIyLCBpZ25vcmluZyBjYXNlICovCnN0YXRpYyBCT09MIG1zaV9zdHJlcXVhbChMUENXU1RSIHN0cjEsIExQQ1NUUiBzdHIyKQp7CglEV09SRCBsZW4sIHJldDsKCUxQV1NUUiBzdHJXOwoKCWxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgc3RyMiwgLTEsIE5VTEwsIDApOwoJaWYoICFsZW4gKQoJCXJldHVybiBUUlVFOwoJaWYoIGxzdHJsZW5XKHN0cjEpICE9IChsZW4tMSkgKQoJCXJldHVybiBUUlVFOwoJc3RyVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpKmxlbik7CglNdWx0aUJ5dGVUb1dpZGVDaGFyKCBDUF9BQ1AsIDAsIHN0cjIsIC0xLCBzdHJXLCBsZW4pOwoJcmV0ID0gQ29tcGFyZVN0cmluZ1coR2V0VGhyZWFkTG9jYWxlKCksIE5PUk1fSUdOT1JFQ0FTRSwgc3RyMSwgbGVuLCBzdHJXLCBsZW4pOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyVyk7CglyZXR1cm4gKHJldCAhPSBDU1RSX0VRVUFMKTsKfQoKLyogc3RyMiBpcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHN0cjEsIGlnbm9yaW5nIGNhc2UgKi8Kc3RhdGljIEJPT0wgbXNpX3N0cnByZWZpeChMUENXU1RSIHN0cjEsIExQQ1NUUiBzdHIyKQp7CglEV09SRCBsZW4sIHJldDsKCUxQV1NUUiBzdHJXOwoKCWxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgc3RyMiwgLTEsIE5VTEwsIDApOwoJaWYoICFsZW4gKQoJCXJldHVybiBUUlVFOwoJaWYoIGxzdHJsZW5XKHN0cjEpIDwgKGxlbi0xKSApCgkJcmV0dXJuIFRSVUU7CglzdHJXID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXQ0hBUikqbGVuKTsKCU11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgc3RyMiwgLTEsIHN0clcsIGxlbik7CglyZXQgPSBDb21wYXJlU3RyaW5nVyhHZXRUaHJlYWRMb2NhbGUoKSwgTk9STV9JR05PUkVDQVNFLCBzdHIxLCBsZW4tMSwgc3RyVywgbGVuLTEpOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyVyk7CglyZXR1cm4gKHJldCAhPSBDU1RSX0VRVUFMKTsKfQoKc3RhdGljIFZPSUQgKkxvYWRQcm9jKExQQ1dTVFIgRGxsTmFtZSwgTFBDU1RSIFByb2NOYW1lLCBITU9EVUxFKiBEbGxIYW5kbGUpCnsKCVZPSUQqICgqcHJvYykodm9pZCk7CgoJKkRsbEhhbmRsZSA9IExvYWRMaWJyYXJ5RXhXKERsbE5hbWUsIE5VTEwsIExPQURfV0lUSF9BTFRFUkVEX1NFQVJDSF9QQVRIKTsKCWlmKCEqRGxsSGFuZGxlKQoJewoJCWZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvYWQgZGxsICVzXG4iLCB3aW5lX2RiZ3N0cl93KERsbE5hbWUpKTsKCQlFeGl0UHJvY2VzcygxKTsKCX0KCXByb2MgPSAoVk9JRCAqKSBHZXRQcm9jQWRkcmVzcygqRGxsSGFuZGxlLCBQcm9jTmFtZSk7CglpZighcHJvYykKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIkRsbCAlcyBkb2VzIG5vdCBpbXBsZW1lbnQgZnVuY3Rpb24gJXNcbiIsCgkJCXdpbmVfZGJnc3RyX3coRGxsTmFtZSksIFByb2NOYW1lKTsKCQlGcmVlTGlicmFyeSgqRGxsSGFuZGxlKTsKCQlFeGl0UHJvY2VzcygxKTsKCX0KCglyZXR1cm4gcHJvYzsKfQoKc3RhdGljIERXT1JEIERvRGxsUmVnaXN0ZXJTZXJ2ZXIoTFBDV1NUUiBEbGxOYW1lKQp7CglIUkVTVUxUIGhyOwoJRExMUkVHSVNURVJTRVJWRVIgcGZEbGxSZWdpc3RlclNlcnZlciA9IE5VTEw7CglITU9EVUxFIERsbEhhbmRsZSA9IE5VTEw7CgoJcGZEbGxSZWdpc3RlclNlcnZlciA9IExvYWRQcm9jKERsbE5hbWUsICJEbGxSZWdpc3RlclNlcnZlciIsICZEbGxIYW5kbGUpOwoKCWhyID0gcGZEbGxSZWdpc3RlclNlcnZlcigpOwoJaWYoRkFJTEVEKGhyKSkKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCB0byByZWdpc3RlciBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJCXJldHVybiAxOwoJfQoJcHJpbnRmKCJTdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCBkbGwgJXNcbiIsIHdpbmVfZGJnc3RyX3coRGxsTmFtZSkpOwoJaWYoRGxsSGFuZGxlKQoJCUZyZWVMaWJyYXJ5KERsbEhhbmRsZSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIERXT1JEIERvRGxsVW5yZWdpc3RlclNlcnZlcihMUENXU1RSIERsbE5hbWUpCnsKCUhSRVNVTFQgaHI7CglETExVTlJFR0lTVEVSU0VSVkVSIHBmRGxsVW5yZWdpc3RlclNlcnZlciA9IE5VTEw7CglITU9EVUxFIERsbEhhbmRsZSA9IE5VTEw7CgoJcGZEbGxVbnJlZ2lzdGVyU2VydmVyID0gTG9hZFByb2MoRGxsTmFtZSwgIkRsbFVucmVnaXN0ZXJTZXJ2ZXIiLCAmRGxsSGFuZGxlKTsKCglociA9IHBmRGxsVW5yZWdpc3RlclNlcnZlcigpOwoJaWYoRkFJTEVEKGhyKSkKCXsKCQlmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCB0byB1bnJlZ2lzdGVyIGRsbCAlc1xuIiwgd2luZV9kYmdzdHJfdyhEbGxOYW1lKSk7CgkJcmV0dXJuIDE7Cgl9CglwcmludGYoIlN1Y2Nlc3NmdWxseSB1bnJlZ2lzdGVyZWQgZGxsICVzXG4iLCB3aW5lX2RiZ3N0cl93KERsbE5hbWUpKTsKCWlmKERsbEhhbmRsZSkKCQlGcmVlTGlicmFyeShEbGxIYW5kbGUpOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIHN0YXRlIG1hY2hpbmUgdG8gYnJlYWsgdXAgdGhlIGNvbW1hbmQgbGluZSBwcm9wZXJseQogKi8KCmVudW0gY2hvbXBfc3RhdGUKewoJY3Nfd2hpdGVzcGFjZSwKCWNzX3Rva2VuLAoJY3NfcXVvdGUKfTsKCnN0YXRpYyBpbnQgY2hvbXAoIFdDSEFSICpzdHIgKQp7CgllbnVtIGNob21wX3N0YXRlIHN0YXRlID0gY3Nfd2hpdGVzcGFjZTsKCVdDSEFSICpwLCAqb3V0OwoJaW50IGNvdW50ID0gMCwgaWdub3JlOwoKCWZvciggcCA9IHN0ciwgb3V0ID0gc3RyOyAqcDsgcCsrICkKCXsKCQlpZ25vcmUgPSAxOwoJCXN3aXRjaCggc3RhdGUgKQoJCXsKCQljYXNlIGNzX3doaXRlc3BhY2U6CgkJCXN3aXRjaCggKnAgKQoJCQl7CgkJCWNhc2UgJyAnOgoJCQkJYnJlYWs7CgkJCWNhc2UgJyInOgoJCQkJc3RhdGUgPSBjc19xdW90ZTsKCQkJCWNvdW50Kys7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWNvdW50Kys7CgkJCQlpZ25vcmUgPSAwOwoJCQkJc3RhdGUgPSBjc190b2tlbjsKCQkJfQoJCQlicmVhazsKCgkJY2FzZSBjc190b2tlbjoKCQkJc3dpdGNoKCAqcCApCgkJCXsKCQkJY2FzZSAnIic6CgkJCQlzdGF0ZSA9IGNzX3F1b3RlOwoJCQkJYnJlYWs7CgkJCWNhc2UgJyAnOgoJCQkJc3RhdGUgPSBjc193aGl0ZXNwYWNlOwoJCQkJKm91dCsrID0gMDsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJaWdub3JlID0gMDsKCQkJfQoJCQlicmVhazsKCgkJY2FzZSBjc19xdW90ZToKCQkJc3dpdGNoKCAqcCApCgkJCXsKCQkJY2FzZSAnIic6CgkJCQlzdGF0ZSA9IGNzX3Rva2VuOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlpZ25vcmUgPSAwOwoJCQl9CgkJCWJyZWFrOwoJCX0KCQlpZiggIWlnbm9yZSApCgkJCSpvdXQrKyA9ICpwOwoJfQoKCSpvdXQgPSAwOwoKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIHZvaWQgcHJvY2Vzc19hcmdzKCBXQ0hBUiAqY21kbGluZSwgaW50ICpwYXJnYywgV0NIQVIgKioqcGFyZ3YgKQp7CglXQ0hBUiAqKmFyZ3YsICpwID0gbXNpX3N0cmR1cChjbWRsaW5lKTsKCWludCBpLCBuOwoKCW4gPSBjaG9tcCggcCApOwoJYXJndiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YgKFdDSEFSKikqKG4rMSkpOwoJZm9yKCBpPTA7IGk8bjsgaSsrICkKCXsKCQlhcmd2W2ldID0gcDsKCQlwICs9IGxzdHJsZW5XKHApICsgMTsKCX0KCWFyZ3ZbaV0gPSBOVUxMOwoKCSpwYXJnYyA9IG47CgkqcGFyZ3YgPSBhcmd2Owp9CgpzdGF0aWMgQk9PTCBwcm9jZXNzX2FyZ3NfZnJvbV9yZWcoIExQV1NUUiBpZGVudCwgaW50ICpwYXJnYywgV0NIQVIgKioqcGFyZ3YgKQp7CglMT05HIHI7CglIS0VZIGhrZXkgPSAwLCBoa2V5QXJncyA9IDA7CglEV09SRCBzeiA9IDAsIHR5cGUgPSAwOwoJTFBXU1RSIGJ1ZiA9IE5VTEw7CglCT09MIHJldCA9IEZBTFNFOwoKCXIgPSBSZWdPcGVuS2V5VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIEluc3RhbGxSdW5PbmNlLCAmaGtleSk7CglpZihyICE9IEVSUk9SX1NVQ0NFU1MpCgkJcmV0dXJuIEZBTFNFOwoJciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgaWRlbnQsIDAsICZ0eXBlLCAwLCAmc3opOwoJaWYociA9PSBFUlJPUl9TVUNDRVNTICYmIHR5cGUgPT0gUkVHX1NaKQoJewoJCWJ1ZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzeik7CgkJciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgaWRlbnQsIDAsICZ0eXBlLCAoTFBCWVRFKWJ1ZiwgJnN6KTsKCQlpZiggciA9PSBFUlJPUl9TVUNDRVNTICkKCQl7CgkJCXByb2Nlc3NfYXJncyhidWYsIHBhcmdjLCBwYXJndik7CgkJCXJldCA9IFRSVUU7CgkJfQoJfQoJUmVnQ2xvc2VLZXkoaGtleUFyZ3MpOwoJcmV0dXJuIHJldDsKfQoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KQp7CglpbnQgaTsKCUJPT0wgRnVuY3Rpb25JbnN0YWxsID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uSW5zdGFsbEFkbWluID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uUmVwYWlyID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uQWR2ZXJ0aXNlID0gRkFMU0U7CglCT09MIEZ1bmN0aW9uUGF0Y2ggPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25EbGxSZWdpc3RlclNlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvbkRsbFVucmVnaXN0ZXJTZXJ2ZXIgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25SZWdTZXJ2ZXIgPSBGQUxTRTsKCUJPT0wgRnVuY3Rpb25VbnJlZ1NlcnZlciA9IEZBTFNFOwoJQk9PTCBGdW5jdGlvblVua25vd24gPSBGQUxTRTsKCglMUFdTVFIgUGFja2FnZU5hbWUgPSBOVUxMOwoJTFBXU1RSIFByb3BlcnRpZXMgPSBOVUxMOwoJc3RydWN0IHN0cmluZ19saXN0ICpwcm9wZXJ0eV9saXN0ID0gTlVMTDsKCglEV09SRCBSZXBhaXJNb2RlID0gMDsKCglEV09SRCBBZHZlcnRpc2VNb2RlID0gMDsKCUxQV1NUUiBUcmFuc2Zvcm1zID0gTlVMTDsKCXN0cnVjdCBzdHJpbmdfbGlzdCAqdHJhbnNmb3JtX2xpc3QgPSBOVUxMOwoJTEFOR0lEIExhbmd1YWdlID0gMDsKCglEV09SRCBMb2dNb2RlID0gMDsKCUxQV1NUUiBMb2dGaWxlTmFtZSA9IE5VTEw7CglEV09SRCBMb2dBdHRyaWJ1dGVzID0gMDsKCglMUFdTVFIgUGF0Y2hGaWxlTmFtZSA9IE5VTEw7CglJTlNUQUxMVFlQRSBJbnN0YWxsVHlwZSA9IElOU1RBTExUWVBFX0RFRkFVTFQ7CgoJSU5TVEFMTFVJTEVWRUwgSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9GVUxMOwoKCUxQV1NUUiBEbGxOYW1lID0gTlVMTDsKCURXT1JEIFJldHVybkNvZGU7CglMUFdTVFIgKmFyZ3ZXID0gTlVMTDsKCgkvKiBvdmVyd3JpdGUgdGhlIGNvbW1hbmQgbGluZSAqLwoJcHJvY2Vzc19hcmdzKCBHZXRDb21tYW5kTGluZVcoKSwgJmFyZ2MsICZhcmd2VyApOwoKCS8qCgkgKiBJZiB0aGUgYXJncyBiZWdpbiB3aXRoIC9AIElERU5UIHRoZW4gd2UgbmVlZCB0byBsb2FkIHRoZSByZWFsCgkgKiBjb21tYW5kIGxpbmUgb3V0IG9mIHRoZSBSdW5PbmNlRW50cmllcyBrZXkgaW4gdGhlIHJlZ2lzdHJ5LgoJICogIFdlIGRvIHRoYXQgYmVmb3JlIHN0YXJ0aW5nIHRvIHByb2Nlc3MgdGhlIHJlYWwgY29tbWFuZGxpbmUsCgkgKiB0aGVuIG92ZXJ3cml0ZSB0aGUgY29tbWFuZGxpbmUgYWdhaW4uCgkgKi8KCWlmKCFtc2lfc3RyZXF1YWwoYXJndldbMV0sICIvQCIpKQoJewoJCWlmKCFwcm9jZXNzX2FyZ3NfZnJvbV9yZWcoIGFyZ3ZXWzJdLCAmYXJnYywgJmFyZ3ZXICkpCgkJCXJldHVybiAxOwoJfQoKCWZvcihpID0gMTsgaSA8IGFyZ2M7IGkrKykKCXsKCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoKCQlpZiAoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi9yZWdzZXJ2ZXIiKSkKCQl7CgkJCUZ1bmN0aW9uUmVnU2VydmVyID0gVFJVRTsKCQl9CgkJZWxzZSBpZiAoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi91bnJlZ3NlcnZlciIpIHx8ICFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvdW5yZWdpc3RlciIpKQoJCXsKCQkJRnVuY3Rpb25VbnJlZ1NlcnZlciA9IFRSVUU7CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJwcmVmaXgoYXJndldbaV0sICIvaSIpKQoJCXsKCQkJTFBXU1RSIGFyZ3ZXaSA9IGFyZ3ZXW2ldOwoJCQlGdW5jdGlvbkluc3RhbGwgPSBUUlVFOwoJCQlpZihsc3RybGVuVyhhcmd2V2kpID4gMikKCQkJCWFyZ3ZXaSArPSAyOwoJCQllbHNlCgkJCXsKCQkJCWkrKzsKCQkJCWlmKGkgPj0gYXJnYykKCQkJCQlTaG93VXNhZ2UoMSk7CgkJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQkJYXJndldpID0gYXJndldbaV07CgkJCX0KCQkJUGFja2FnZU5hbWUgPSBhcmd2V2k7CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi9hIikpCgkJewoJCQlGdW5jdGlvbkluc3RhbGwgPSBUUlVFOwoJCQlGdW5jdGlvbkluc3RhbGxBZG1pbiA9IFRSVUU7CgkJCUluc3RhbGxUeXBlID0gSU5TVEFMTFRZUEVfTkVUV09SS19JTUFHRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJCVN0cmluZ0xpc3RBcHBlbmQoJnByb3BlcnR5X2xpc3QsIEFjdGlvbkFkbWluKTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cnByZWZpeChhcmd2V1tpXSwgIi9mIikpCgkJewoJCQlpbnQgajsKCQkJaW50IGxlbiA9IGxzdHJsZW5XKGFyZ3ZXW2ldKTsKCQkJRnVuY3Rpb25SZXBhaXIgPSBUUlVFOwoJCQlmb3IoaiA9IDI7IGogPCBsZW47IGorKykKCQkJewoJCQkJc3dpdGNoKGFyZ3ZXW2ldW2pdKQoJCQkJewoJCQkJCWNhc2UgJ1AnOgoJCQkJCWNhc2UgJ3AnOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRU1JU1NJTkc7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ08nOgoJCQkJCWNhc2UgJ28nOgoJCQkJCQlSZXBhaXJNb2RlIHw9IFJFSU5TVEFMTE1PREVfRklMRU9MREVSVkVSU0lPTjsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnRSc6CgkJCQkJY2FzZSAnZSc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFRVFVQUxWRVJTSU9OOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdEJzoKCQkJCQljYXNlICdkJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVFWEFDVDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnQyc6CgkJCQkJY2FzZSAnYyc6CgkJCQkJCVJlcGFpck1vZGUgfD0gUkVJTlNUQUxMTU9ERV9GSUxFVkVSSUZZOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdBJzoKCQkJCQljYXNlICdhJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX0ZJTEVSRVBMQUNFOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdVJzoKCQkJCQljYXNlICd1JzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX1VTRVJEQVRBOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdNJzoKCQkJCQljYXNlICdtJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX01BQ0hJTkVEQVRBOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdTJzoKCQkJCQljYXNlICdzJzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX1NIT1JUQ1VUOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdWJzoKCQkJCQljYXNlICd2JzoKCQkJCQkJUmVwYWlyTW9kZSB8PSBSRUlOU1RBTExNT0RFX1BBQ0tBR0U7CgkJCQkJCWJyZWFrOwoJCQkJCWRlZmF1bHQ6CgkJCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBvcHRpb24gXCIlY1wiIGluIFJlcGFpciBtb2RlXG4iLCBhcmd2V1tpXVtqXSk7CgkJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJCWlmKGxlbiA9PSAyKQoJCQl7CgkJCQlSZXBhaXJNb2RlID0gUkVJTlNUQUxMTU9ERV9GSUxFTUlTU0lORyB8CgkJCQkJUkVJTlNUQUxMTU9ERV9GSUxFRVFVQUxWRVJTSU9OIHwKCQkJCQlSRUlOU1RBTExNT0RFX0ZJTEVWRVJJRlkgfAoJCQkJCVJFSU5TVEFMTE1PREVfTUFDSElORURBVEEgfAoJCQkJCVJFSU5TVEFMTE1PREVfU0hPUlRDVVQ7CgkJCX0KCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi94IikpCgkJewoJCQlGdW5jdGlvbkluc3RhbGwgPSBUUlVFOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXTsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmcHJvcGVydHlfbGlzdCwgUmVtb3ZlQWxsKTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cnByZWZpeChhcmd2V1tpXSwgIi9qIikpCgkJewoJCQlpbnQgajsKCQkJaW50IGxlbiA9IGxzdHJsZW5XKGFyZ3ZXW2ldKTsKCQkJRnVuY3Rpb25BZHZlcnRpc2UgPSBUUlVFOwoJCQlmb3IoaiA9IDI7IGogPCBsZW47IGorKykKCQkJewoJCQkJc3dpdGNoKGFyZ3ZXW2ldW2pdKQoJCQkJewoJCQkJCWNhc2UgJ1UnOgoJCQkJCWNhc2UgJ3UnOgoJCQkJCQlBZHZlcnRpc2VNb2RlID0gQURWRVJUSVNFRkxBR1NfVVNFUkFTU0lHTjsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnTSc6CgkJCQkJY2FzZSAnbSc6CgkJCQkJCUFkdmVydGlzZU1vZGUgPSBBRFZFUlRJU0VGTEFHU19NQUNISU5FQVNTSUdOOwoJCQkJCQlicmVhazsKCQkJCQlkZWZhdWx0OgoJCQkJCQlmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gb3B0aW9uIFwiJWNcIiBpbiBBZHZlcnRpc2UgbW9kZVxuIiwgYXJndldbaV1bal0pOwoJCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJUGFja2FnZU5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAidSIpKQoJCXsKCQkJRnVuY3Rpb25BZHZlcnRpc2UgPSBUUlVFOwoJCQlBZHZlcnRpc2VNb2RlID0gQURWRVJUSVNFRkxBR1NfVVNFUkFTU0lHTjsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhY2thZ2VOYW1lID0gYXJndldbaV07CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIm0iKSkKCQl7CgkJCUZ1bmN0aW9uQWR2ZXJ0aXNlID0gVFJVRTsKCQkJQWR2ZXJ0aXNlTW9kZSA9IEFEVkVSVElTRUZMQUdTX01BQ0hJTkVBU1NJR047CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIvdCIpKQoJCXsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVN0cmluZ0xpc3RBcHBlbmQoJnRyYW5zZm9ybV9saXN0LCBhcmd2V1tpXSk7CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJwcmVmaXgoYXJndldbaV0sICJUUkFOU0ZPUk1TPSIpKQoJCXsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmdHJhbnNmb3JtX2xpc3QsIGFyZ3ZXW2ldKzExKTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL2ciKSkKCQl7CgkJCWkrKzsKCQkJaWYoaSA+PSBhcmdjKQoJCQkJU2hvd1VzYWdlKDEpOwoJCQlXSU5FX1RSQUNFKCJhcmd2V1slZF0gPSAlc1xuIiwgaSwgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSkpOwoJCQlMYW5ndWFnZSA9IG1zaV9hdG91KGFyZ3ZXW2ldKTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cnByZWZpeChhcmd2V1tpXSwgIi9sIikpCgkJewoJCQlpbnQgajsKCQkJaW50IGxlbiA9IGxzdHJsZW5XKGFyZ3ZXW2ldKTsKCQkJZm9yKGogPSAyOyBqIDwgbGVuOyBqKyspCgkJCXsKCQkJCXN3aXRjaChhcmd2V1tpXVtqXSkKCQkJCXsKCQkJCQljYXNlICdJJzoKCQkJCQljYXNlICdpJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9JTkZPOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdXJzoKCQkJCQljYXNlICd3JzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9XQVJOSU5HOwoJCQkJCQlicmVhazsKCQkJCQljYXNlICdFJzoKCQkJCQljYXNlICdlJzoKCQkJCQkJTG9nTW9kZSB8PSBJTlNUQUxMTE9HTU9ERV9FUlJPUjsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnQSc6CgkJCQkJY2FzZSAnYSc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfQUNUSU9OU1RBUlQ7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1InOgoJCQkJCWNhc2UgJ3InOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0FDVElPTkRBVEE7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1UnOgoJCQkJCWNhc2UgJ3UnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX1VTRVI7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ0MnOgoJCQkJCWNhc2UgJ2MnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0NPTU1PTkRBVEE7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ00nOgoJCQkJCWNhc2UgJ20nOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX0ZBVEFMRVhJVDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnTyc6CgkJCQkJY2FzZSAnbyc6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfT1VUT0ZESVNLU1BBQ0U7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJ1AnOgoJCQkJCWNhc2UgJ3AnOgoJCQkJCQlMb2dNb2RlIHw9IElOU1RBTExMT0dNT0RFX1BST1BFUlRZRFVNUDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnVic6CgkJCQkJY2FzZSAndic6CgkJCQkJCUxvZ01vZGUgfD0gSU5TVEFMTExPR01PREVfVkVSQk9TRTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnKic6CgkJCQkJCUxvZ01vZGUgPSBJTlNUQUxMTE9HTU9ERV9GQVRBTEVYSVQgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfRVJST1IgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfV0FSTklORyB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9VU0VSIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0lORk8gfAoJCQkJCQkJSU5TVEFMTExPR01PREVfUkVTT0xWRVNPVVJDRSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9PVVRPRkRJU0tTUEFDRSB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9BQ1RJT05TVEFSVCB8CgkJCQkJCQlJTlNUQUxMTE9HTU9ERV9BQ1RJT05EQVRBIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0NPTU1PTkRBVEEgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfUFJPUEVSVFlEVU1QIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1BST0dSRVNTIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX0lOSVRJQUxJWkUgfAoJCQkJCQkJSU5TVEFMTExPR01PREVfVEVSTUlOQVRFIHwKCQkJCQkJCUlOU1RBTExMT0dNT0RFX1NIT1dESUFMT0c7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgJysnOgoJCQkJCQlMb2dBdHRyaWJ1dGVzIHw9IElOU1RBTExMT0dBVFRSSUJVVEVTX0FQUEVORDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnISc6CgkJCQkJCUxvZ0F0dHJpYnV0ZXMgfD0gSU5TVEFMTExPR0FUVFJJQlVURVNfRkxVU0hFQUNITElORTsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCUxvZ0ZpbGVOYW1lID0gYXJndldbaV07CgkJCWlmKE1zaUVuYWJsZUxvZ1coTG9nTW9kZSwgTG9nRmlsZU5hbWUsIExvZ0F0dHJpYnV0ZXMpICE9IEVSUk9SX1NVQ0NFU1MpCgkJCXsKCQkJCWZwcmludGYoc3RkZXJyLCAiTG9nZ2luZyBpbiAlcyAoMHglMDhseCwgJWx1KSBmYWlsZWRcbiIsCgkJCQkJIHdpbmVfZGJnc3RyX3coTG9nRmlsZU5hbWUpLCBMb2dNb2RlLCBMb2dBdHRyaWJ1dGVzKTsKCQkJCUV4aXRQcm9jZXNzKDEpOwoJCQl9CgkJfQoJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSwgIi9wIikpCgkJewoJCQlGdW5jdGlvblBhdGNoID0gVFJVRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCVBhdGNoRmlsZU5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cnByZWZpeChhcmd2V1tpXSwgIi9xIikpCgkJewoJCQlpZihsc3RybGVuVyhhcmd2V1tpXSkgPT0gMiB8fCAhbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJuIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfTk9ORTsKCQkJfQoJCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgImIiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9CQVNJQzsKCQkJfQoJCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgInIiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9SRURVQ0VEOwoJCQl9CgkJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiZiIpKQoJCQl7CgkJCQlJbnN0YWxsVUlMZXZlbCA9IElOU1RBTExVSUxFVkVMX0ZVTEx8SU5TVEFMTFVJTEVWRUxfRU5ERElBTE9HOwoJCQl9CgkJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAibisiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9OT05FfElOU1RBTExVSUxFVkVMX0VORERJQUxPRzsKCQkJfQoJCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0rMiwgImIrIikpCgkJCXsKCQkJCUluc3RhbGxVSUxldmVsID0gSU5TVEFMTFVJTEVWRUxfQkFTSUN8SU5TVEFMTFVJTEVWRUxfRU5ERElBTE9HOwoJCQl9CgkJCWVsc2UgaWYoIW1zaV9zdHJlcXVhbChhcmd2V1tpXSsyLCAiYi0iKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9CQVNJQ3xJTlNUQUxMVUlMRVZFTF9QUk9HUkVTU09OTFk7CgkJCX0KCQkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldKzIsICJiKyEiKSkKCQkJewoJCQkJSW5zdGFsbFVJTGV2ZWwgPSBJTlNUQUxMVUlMRVZFTF9CQVNJQ3xJTlNUQUxMVUlMRVZFTF9FTkRESUFMT0c7CgkJCQlXSU5FX0ZJWE1FKCJVbmtub3duIG1vZGlmaWVyOiAhXG4iKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBvcHRpb24gXCIlc1wiIGZvciBVSSBsZXZlbFxuIiwKCQkJCQkgd2luZV9kYmdzdHJfdyhhcmd2V1tpXSsyKSk7CgkJCX0KCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL3kiKSkKCQl7CgkJCUZ1bmN0aW9uRGxsUmVnaXN0ZXJTZXJ2ZXIgPSBUUlVFOwoJCQlpKys7CgkJCWlmKGkgPj0gYXJnYykKCQkJCVNob3dVc2FnZSgxKTsKCQkJV0lORV9UUkFDRSgiYXJndldbJWRdID0gJXNcbiIsIGksIHdpbmVfZGJnc3RyX3coYXJndldbaV0pKTsKCQkJRGxsTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCQllbHNlIGlmKCFtc2lfc3RyZXF1YWwoYXJndldbaV0sICIveiIpKQoJCXsKCQkJRnVuY3Rpb25EbGxVbnJlZ2lzdGVyU2VydmVyID0gVFJVRTsKCQkJaSsrOwoJCQlpZihpID49IGFyZ2MpCgkJCQlTaG93VXNhZ2UoMSk7CgkJCVdJTkVfVFJBQ0UoImFyZ3ZXWyVkXSA9ICVzXG4iLCBpLCB3aW5lX2RiZ3N0cl93KGFyZ3ZXW2ldKSk7CgkJCURsbE5hbWUgPSBhcmd2V1tpXTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL2giKSB8fCAhbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiLz8iKSkKCQl7CgkJCVNob3dVc2FnZSgwKTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL20iKSkKCQl7CgkJCUZ1bmN0aW9uVW5rbm93biA9IFRSVUU7CgkJCVdJTkVfRklYTUUoIlVua25vd24gcGFyYW1ldGVyIC9tXG4iKTsKCQl9CgkJZWxzZSBpZighbXNpX3N0cmVxdWFsKGFyZ3ZXW2ldLCAiL0QiKSkKCQl7CgkJCUZ1bmN0aW9uVW5rbm93biA9IFRSVUU7CgkJCVdJTkVfRklYTUUoIlVua25vd24gcGFyYW1ldGVyIC9EXG4iKTsKCQl9CgkJZWxzZSBpZihzdHJjaHJXKGFyZ3ZXW2ldLCAnPScpKQoJCXsKCQkJU3RyaW5nTGlzdEFwcGVuZCgmcHJvcGVydHlfbGlzdCwgYXJndldbaV0pOwoJCX0KCQllbHNlCgkJewoJCQlGdW5jdGlvbkluc3RhbGwgPSBUUlVFOwoJCQlQYWNrYWdlTmFtZSA9IGFyZ3ZXW2ldOwoJCX0KCX0KCgkvKiBzdGFydCB0aGUgR1VJICovCglNc2lTZXRJbnRlcm5hbFVJKEluc3RhbGxVSUxldmVsLCBOVUxMKTsKCglQcm9wZXJ0aWVzID0gYnVpbGRfcHJvcGVydGllcyggcHJvcGVydHlfbGlzdCApOwoJVHJhbnNmb3JtcyA9IGJ1aWxkX3RyYW5zZm9ybXMoIHRyYW5zZm9ybV9saXN0ICk7CgoJaWYoRnVuY3Rpb25JbnN0YWxsQWRtaW4gJiYgRnVuY3Rpb25QYXRjaCkKCQlGdW5jdGlvbkluc3RhbGwgPSBGQUxTRTsKCglSZXR1cm5Db2RlID0gMTsKCWlmKEZ1bmN0aW9uSW5zdGFsbCkKCXsKCQlpZihJc1Byb2R1Y3RDb2RlKFBhY2thZ2VOYW1lKSkKCQkJUmV0dXJuQ29kZSA9IE1zaUNvbmZpZ3VyZVByb2R1Y3RFeFcoUGFja2FnZU5hbWUsIDAsIElOU1RBTExTVEFURV9ERUZBVUxULCBQcm9wZXJ0aWVzKTsKCQllbHNlCgkJCVJldHVybkNvZGUgPSBNc2lJbnN0YWxsUHJvZHVjdFcoUGFja2FnZU5hbWUsIFByb3BlcnRpZXMpOwoJfQoJZWxzZSBpZihGdW5jdGlvblJlcGFpcikKCXsKCQlpZihJc1Byb2R1Y3RDb2RlKFBhY2thZ2VOYW1lKSkKCQkJV0lORV9GSVhNRSgiUHJvZHVjdCBjb2RlIHRyZWF0bWVudCBub3QgaW1wbGVtZW50ZWQgeWV0XG4iKTsKCQllbHNlCgkJCVJldHVybkNvZGUgPSBNc2lSZWluc3RhbGxQcm9kdWN0VyhQYWNrYWdlTmFtZSwgUmVwYWlyTW9kZSk7Cgl9CgllbHNlIGlmKEZ1bmN0aW9uQWR2ZXJ0aXNlKQoJewoJCVJldHVybkNvZGUgPSBNc2lBZHZlcnRpc2VQcm9kdWN0VyhQYWNrYWdlTmFtZSwgKExQV1NUUikgQWR2ZXJ0aXNlTW9kZSwgVHJhbnNmb3JtcywgTGFuZ3VhZ2UpOwoJfQoJZWxzZSBpZihGdW5jdGlvblBhdGNoKQoJewoJCVJldHVybkNvZGUgPSBNc2lBcHBseVBhdGNoVyhQYXRjaEZpbGVOYW1lLCBQYWNrYWdlTmFtZSwgSW5zdGFsbFR5cGUsIFByb3BlcnRpZXMpOwoJfQoJZWxzZSBpZihGdW5jdGlvbkRsbFJlZ2lzdGVyU2VydmVyKQoJewoJCVJldHVybkNvZGUgPSBEb0RsbFJlZ2lzdGVyU2VydmVyKERsbE5hbWUpOwoJfQoJZWxzZSBpZihGdW5jdGlvbkRsbFVucmVnaXN0ZXJTZXJ2ZXIpCgl7CgkJUmV0dXJuQ29kZSA9IERvRGxsVW5yZWdpc3RlclNlcnZlcihEbGxOYW1lKTsKCX0KCWVsc2UgaWYgKEZ1bmN0aW9uUmVnU2VydmVyKQoJewoJCVdJTkVfRklYTUUoICIvcmVnc2VydmVyIG5vdCBpbXBsZW1lbnRlZCB5ZXQsIGlnbm9yaW5nXG4iICk7Cgl9CgllbHNlIGlmIChGdW5jdGlvblVucmVnU2VydmVyKQoJewoJCVdJTkVfRklYTUUoICIvdW5yZWdzZXJ2ZXIgbm90IGltcGxlbWVudGVkIHlldCwgaWdub3JpbmdcbiIgKTsKCX0KCWVsc2UgaWYgKEZ1bmN0aW9uVW5rbm93bikKCXsKCQlXSU5FX0ZJWE1FKCAiVW5rbm93biBmdW5jdGlvbiwgaWdub3JpbmdcbiIgKTsKCX0KCWVsc2UKCQlTaG93VXNhZ2UoMSk7CgoJcmV0dXJuIFJldHVybkNvZGU7Cn0K