LyoKICogc25tcGRmLmMgLSBkaXNwbGF5IGRpc2sgc3BhY2UgdXNhZ2Ugb24gYSBuZXR3b3JrIGVudGl0eSB2aWEgU05NUC4KICoKICovCgovKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb3B5cmlnaHQocykuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCUNvcHlyaWdodCAxOTg4LCAxOTg5LCAxOTkxLCAxOTkyIGJ5IENhcm5lZ2llIE1lbGxvbiBVbml2ZXJzaXR5CgogICAgICAgICAgICAgICAgICAgICAgQWxsIFJpZ2h0cyBSZXNlcnZlZAoKUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzIApkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBhbmQgd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIApwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0CmJvdGggdGhhdCBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiAKc3VwcG9ydGluZyBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBDTVUgbm90IGJlCnVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZQpzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICAKCkNNVSBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwgSU5DTFVESU5HCkFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTyBFVkVOVCBTSEFMTApDTVUgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SCkFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywKV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIgVE9SVElPVVMgQUNUSU9OLApBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTClNPRlRXQVJFLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBpbmNsdWRlIDx0aW1lLmg+CiNlbHNlCiMgaWYgSEFWRV9TWVNfVElNRV9ICiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZWxzZQojICBpbmNsdWRlIDx0aW1lLmg+CiMgZW5kaWYKI2VuZGlmCiNpZiBIQVZFX1NZU19TRUxFQ1RfSAojaW5jbHVkZSA8c3lzL3NlbGVjdC5oPgojZW5kaWYKI2lmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCiNpZiBIQVZFX0FSUEFfSU5FVF9ICiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KCnZvaWQKdXNhZ2Uodm9pZCkKewogICAgZnByaW50ZihzdGRlcnIsICJVc2FnZTogc25tcGRmIFstQ3VdICIpOwogICAgc25tcF9wYXJzZV9hcmdzX3VzYWdlKHN0ZGVycik7CiAgICBmcHJpbnRmKHN0ZGVyciwgIlxuXG4iKTsKICAgIHNubXBfcGFyc2VfYXJnc19kZXNjcmlwdGlvbnMoc3RkZXJyKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXG5zbm1wZGYgb3B0aW9uczpcbiIpOwogICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICJcdC1DdVx0VXNlIFVDRC1TTk1QIGRza1RhYmxlIHRvIGRvIHRoZSBjYWxjdWxhdGlvbnMuXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAiXHRcdFtOb3JtYWxseSB0aGUgSE9TVC1SRVNPVVJDRVMtTUlCIGlzIGNvbnN1bHRlZCBmaXJzdC5dXG4iKTsKfQoKaW50ICAgICAgICAgICAgIHVjZF9taWIgPSAwOwoKc3RhdGljIHZvaWQKb3B0UHJvYyhpbnQgYXJnYywgY2hhciAqY29uc3QgKmFyZ3YsIGludCBvcHQpCnsKICAgIHN3aXRjaCAob3B0KSB7CiAgICBjYXNlICdDJzoKICAgICAgICB3aGlsZSAoKm9wdGFyZykgewogICAgICAgICAgICBzd2l0Y2ggKCpvcHRhcmcrKykgewogICAgICAgICAgICBjYXNlICd1JzoKICAgICAgICAgICAgICAgIHVjZF9taWIgPSAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgIlVua25vd24gZmxhZyBwYXNzZWQgdG8gLUM6ICVjXG4iLCBvcHRhcmdbLTFdKTsKICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCnN0cnVjdCBoclN0b3JhZ2VUYWJsZSB7CiAgICB1X2xvbmcgICAgICAgICAgaHJTdG9yYWdlSW5kZXg7CiAgICBvaWQgICAgICAgICAgICAqaHJTdG9yYWdlVHlwZTsKICAgIGNoYXIgICAgICAgICAgICpoclN0b3JhZ2VEZXNjcjsKICAgIHVfbG9uZyAgICAgICAgICBoclN0b3JhZ2VBbGxvY2F0aW9uVW5pdHM7CiAgICB1X2xvbmcgICAgICAgICAgaHJTdG9yYWdlU2l6ZTsKICAgIHVfbG9uZyAgICAgICAgICBoclN0b3JhZ2VVc2VkOwp9OwoKaW50CmFkZChuZXRzbm1wX3BkdSAqcGR1LCBjb25zdCBjaGFyICptaWJub2RlbmFtZSwKICAgIG9pZCAqIGluZGV4LCBzaXplX3QgaW5kZXhsZW4pCnsKICAgIG9pZCAgICAgICAgICAgICBiYXNlW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCAgICAgICAgICBiYXNlX2xlbmd0aCA9IE1BWF9PSURfTEVOOwoKICAgIG1lbXNldChiYXNlLCAwLCBNQVhfT0lEX0xFTiAqIHNpemVvZihvaWQpKTsKCiAgICBpZiAoIXNubXBfcGFyc2Vfb2lkKG1pYm5vZGVuYW1lLCBiYXNlLCAmYmFzZV9sZW5ndGgpKSB7CiAgICAgICAgc25tcF9wZXJyb3IobWlibm9kZW5hbWUpOwogICAgICAgIGZwcmludGYoc3RkZXJyLCAiY291bGRuJ3QgZmluZCBtaWIgbm9kZSAlcywgZ2l2aW5nIHVwXG4iLAogICAgICAgICAgICAgICAgbWlibm9kZW5hbWUpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgogICAgaWYgKGluZGV4ICYmIGluZGV4bGVuKSB7CiAgICAgICAgbWVtY3B5KCYoYmFzZVtiYXNlX2xlbmd0aF0pLCBpbmRleCwgaW5kZXhsZW4gKiBzaXplb2Yob2lkKSk7CiAgICAgICAgYmFzZV9sZW5ndGggKz0gaW5kZXhsZW47CiAgICB9CiAgICBERUJVR01TR1RMKCgiYWRkIiwgImNyZWF0ZWQ6ICIpKTsKICAgIERFQlVHTVNHT0lEKCgiYWRkIiwgYmFzZSwgYmFzZV9sZW5ndGgpKTsKICAgIERFQlVHTVNHKCgiYWRkIiwgIlxuIikpOwogICAgc25tcF9hZGRfbnVsbF92YXIocGR1LCBiYXNlLCBiYXNlX2xlbmd0aCk7CgogICAgcmV0dXJuIGJhc2VfbGVuZ3RoOwp9CgpuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKgpjb2xsZWN0KG5ldHNubXBfc2Vzc2lvbiAqIHNzLCBuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgIG9pZCAqIGJhc2UsIHNpemVfdCBiYXNlX2xlbmd0aCkKewogICAgbmV0c25tcF9wZHUgICAgKnJlc3BvbnNlOwogICAgaW50ICAgICAgICAgICAgIHJ1bm5pbmcgPSAxOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpzYXZlZCA9IE5VTEwsICoqdmxwcCA9ICZzYXZlZDsKICAgIGludCAgICAgICAgICAgICBzdGF0dXM7CgogICAgd2hpbGUgKHJ1bm5pbmcpIHsKICAgICAgICAvKgogICAgICAgICAqIGdvdHRhIGNhdGNoIGVtIGFsbCwgZ290dGEgY2F0Y2ggZW0gYWxsISAKICAgICAgICAgKi8KICAgICAgICBzdGF0dXMgPSBzbm1wX3N5bmNoX3Jlc3BvbnNlKHNzLCBwZHUsICZyZXNwb25zZSk7CiAgICAgICAgaWYgKHN0YXR1cyAhPSBTVEFUX1NVQ0NFU1MgfHwgIXJlc3BvbnNlKSB7CiAgICAgICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXBkZiIsIHNzKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlc3BvbnNlLT5lcnJzdGF0ICE9IFNOTVBfRVJSX05PRVJST1IpIHsKCSAgICBmcHJpbnRmKHN0ZGVyciwgInNubXBkZjogRXJyb3IgaW4gcGFja2V0OiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBzbm1wX2VycnN0cmluZyhyZXNwb25zZS0+ZXJyc3RhdCkpOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KICAgICAgICBpZiAoc25tcF9vaWRfY29tcGFyZShyZXNwb25zZS0+dmFyaWFibGVzLT5uYW1lLAoJCQkgICAgIFNOTVBfTUlOKGJhc2VfbGVuZ3RoLAoJCQkJICAgICAgcmVzcG9uc2UtPnZhcmlhYmxlcy0+bmFtZV9sZW5ndGgpLAoJCQkgICAgIGJhc2UsIGJhc2VfbGVuZ3RoKSAhPSAwKQogICAgICAgICAgICBydW5uaW5nID0gMDsKICAgICAgICBlbHNlIGlmIChyZXNwb25zZS0+dmFyaWFibGVzLT50eXBlID09IFNOTVBfTk9TVUNISU5TVEFOQ0UgfHwKICAgICAgICAgICAgICAgICByZXNwb25zZS0+dmFyaWFibGVzLT50eXBlID09IFNOTVBfTk9TVUNIT0JKRUNUIHx8CiAgICAgICAgICAgICAgICAgcmVzcG9uc2UtPnZhcmlhYmxlcy0+dHlwZSA9PSBTTk1QX0VORE9GTUlCVklFVykKICAgICAgICAgICAgcnVubmluZyA9IDA7CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGdldCByZXNwb25zZSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgICp2bHBwID0gcmVzcG9uc2UtPnZhcmlhYmxlczsKICAgICAgICAgICAgKCp2bHBwKS0+bmV4dF92YXJpYWJsZSA9IE5VTEw7ICAgICAgLyogc2hvdWxkbid0IGJlIGFueSwgYnV0IGp1c3QgaW4gY2FzZSAqLwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogY3JlYXRlIHRoZSBuZXh0IHJlcXVlc3QgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfR0VUTkVYVCk7CiAgICAgICAgICAgIHNubXBfYWRkX251bGxfdmFyKHBkdSwgKCp2bHBwKS0+bmFtZSwgKCp2bHBwKS0+bmFtZV9sZW5ndGgpOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZmluaXNoIGxvb3Agc2V0dXAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB2bHBwID0gJigoKnZscHApLT5uZXh0X3ZhcmlhYmxlKTsKICAgICAgICAgICAgcmVzcG9uc2UtPnZhcmlhYmxlcyA9IE5VTEw7IC8qIGFoaCwgZm9yZ2V0IGFib3V0IGl0ICovCiAgICAgICAgfQogICAgICAgIHNubXBfZnJlZV9wZHUocmVzcG9uc2UpOwogICAgfQogICAgcmV0dXJuIHNhdmVkOwp9CgovKiBDb21wdXRlcyB2YWx1ZSp1bml0cy9kaXZpc29yIGluIGFuIG92ZXJmbG93LXByb29mIHdheS4KICovCnVuc2lnbmVkIGxvbmcKY29udmVydF91bml0cyh1bnNpZ25lZCBsb25nIHZhbHVlLCBzaXplX3QgdW5pdHMsIHNpemVfdCBkaXZpc29yKQp7CiAgICByZXR1cm4gKHVuc2lnbmVkIGxvbmcpKChkb3VibGUpdmFsdWUgKiB1bml0cyAvIChkb3VibGUpZGl2aXNvcik7Cn0KCgppbnQKbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKQp7CiAgICBuZXRzbm1wX3Nlc3Npb24gc2Vzc2lvbiwgKnNzOwogICAgbmV0c25tcF9wZHUgICAgKnBkdTsKICAgIG5ldHNubXBfcGR1ICAgICpyZXNwb25zZTsKICAgIGludCAgICAgICAgICAgICBhcmc7CiAgICBvaWQgICAgICAgICAgICAgYmFzZVtNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgICAgICAgICAgYmFzZV9sZW5ndGg7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpzYXZlZCA9IE5VTEwsICp2bHAgPSBzYXZlZCwgKnZscDI7CiAgICBpbnQgICAgICAgICAgICAgY291bnQgPSAwOwoKICAgIC8qCiAgICAgKiBnZXQgdGhlIGNvbW1vbiBjb21tYW5kIGxpbmUgYXJndW1lbnRzIAogICAgICovCiAgICBzd2l0Y2ggKGFyZyA9IHNubXBfcGFyc2VfYXJncyhhcmdjLCBhcmd2LCAmc2Vzc2lvbiwgIkM6Iiwgb3B0UHJvYykpIHsKICAgIGNhc2UgTkVUU05NUF9QQVJTRV9BUkdTX0VSUk9SOgogICAgICAgIGV4aXQoMSk7CiAgICBjYXNlIE5FVFNOTVBfUEFSU0VfQVJHU19TVUNDRVNTX0VYSVQ6CiAgICAgICAgZXhpdCgwKTsKICAgIGNhc2UgTkVUU05NUF9QQVJTRV9BUkdTX0VSUk9SX1VTQUdFOgogICAgICAgIHVzYWdlKCk7CiAgICAgICAgZXhpdCgxKTsKICAgIGRlZmF1bHQ6CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGFyZyAhPSBhcmdjKSB7CglmcHJpbnRmKHN0ZGVyciwgInNubXBkZjogZXh0cmEgYXJndW1lbnQ6ICVzXG4iLCBhcmd2W2FyZ10pOwoJZXhpdCgxKTsKICAgIH0KCiAgICBTT0NLX1NUQVJUVVA7CgogICAgLyoKICAgICAqIE9wZW4gYW4gU05NUCBzZXNzaW9uLgogICAgICovCiAgICBzcyA9IHNubXBfb3Blbigmc2Vzc2lvbik7CiAgICBpZiAoc3MgPT0gTlVMTCkgewogICAgICAgIC8qCiAgICAgICAgICogZGlhZ25vc2Ugc25tcF9vcGVuIGVycm9ycyB3aXRoIHRoZSBpbnB1dCBuZXRzbm1wX3Nlc3Npb24gcG9pbnRlciAKICAgICAgICAgKi8KICAgICAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wZGYiLCAmc2Vzc2lvbik7CiAgICAgICAgU09DS19DTEVBTlVQOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgogICAgcHJpbnRmKCIlLTE4cyAlMTVzICUxNXMgJTE1cyAlNXNcbiIsICJEZXNjcmlwdGlvbiIsICJzaXplIChrQikiLAogICAgICAgICAgICJVc2VkIiwgIkF2YWlsYWJsZSIsICJVc2VkJSIpOwogICAgaWYgKHVjZF9taWIgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogKiBCZWdpbiBieSBmaW5kaW5nIGFsbCB0aGUgc3RvcmFnZSBwaWVjZXMgdGhhdCBhcmUgb2YKICAgICAgICAgKiAqIHR5cGUgaHJTdG9yYWdlRml4ZWREaXNrLCB3aGljaCBpcyBhIHN0YW5kYXJkIGRpc2suCiAgICAgICAgICovCiAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKFNOTVBfTVNHX0dFVE5FWFQpOwogICAgICAgIGJhc2VfbGVuZ3RoID0KICAgICAgICAgICAgYWRkKHBkdSwgIkhPU1QtUkVTT1VSQ0VTLU1JQjpoclN0b3JhZ2VJbmRleCIsIE5VTEwsIDApOwogICAgICAgIG1lbWNweShiYXNlLCBwZHUtPnZhcmlhYmxlcy0+bmFtZSwgYmFzZV9sZW5ndGggKiBzaXplb2Yob2lkKSk7CgogICAgICAgIHZscCA9IGNvbGxlY3Qoc3MsIHBkdSwgYmFzZSwgYmFzZV9sZW5ndGgpOwoKICAgICAgICB3aGlsZSAodmxwKSB7CiAgICAgICAgICAgIHNpemVfdCAgICAgICAgICB1bml0czsKICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAgIGhzc2l6ZSwgaHN1c2VkOwogICAgICAgICAgICBjaGFyICAgICAgICAgICAgZGVzY3JbU1BSSU5UX01BWF9MRU5dOwogICAgICAgICAgICBpbnQgICAgICAgICAgICAgbGVuOwoKICAgICAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKFNOTVBfTVNHX0dFVCk7CgogICAgICAgICAgICBhZGQocGR1LCAiSE9TVC1SRVNPVVJDRVMtTUlCOmhyU3RvcmFnZURlc2NyIiwKICAgICAgICAgICAgICAgICYodmxwLT5uYW1lW2Jhc2VfbGVuZ3RoXSksIHZscC0+bmFtZV9sZW5ndGggLSBiYXNlX2xlbmd0aCk7CiAgICAgICAgICAgIGFkZChwZHUsICJIT1NULVJFU09VUkNFUy1NSUI6aHJTdG9yYWdlQWxsb2NhdGlvblVuaXRzIiwKICAgICAgICAgICAgICAgICYodmxwLT5uYW1lW2Jhc2VfbGVuZ3RoXSksIHZscC0+bmFtZV9sZW5ndGggLSBiYXNlX2xlbmd0aCk7CiAgICAgICAgICAgIGFkZChwZHUsICJIT1NULVJFU09VUkNFUy1NSUI6aHJTdG9yYWdlU2l6ZSIsCiAgICAgICAgICAgICAgICAmKHZscC0+bmFtZVtiYXNlX2xlbmd0aF0pLCB2bHAtPm5hbWVfbGVuZ3RoIC0gYmFzZV9sZW5ndGgpOwogICAgICAgICAgICBhZGQocGR1LCAiSE9TVC1SRVNPVVJDRVMtTUlCOmhyU3RvcmFnZVVzZWQiLAogICAgICAgICAgICAgICAgJih2bHAtPm5hbWVbYmFzZV9sZW5ndGhdKSwgdmxwLT5uYW1lX2xlbmd0aCAtIGJhc2VfbGVuZ3RoKTsKCiAgICAgICAgICAgIHN0YXR1cyA9IHNubXBfc3luY2hfcmVzcG9uc2Uoc3MsIHBkdSwgJnJlc3BvbnNlKTsKICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSBTVEFUX1NVQ0NFU1MgfHwgIXJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wZGYiLCBzcyk7CiAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2bHAyID0gcmVzcG9uc2UtPnZhcmlhYmxlczsKICAgICAgICAgICAgaWYgKHZscDItPnR5cGUgPT0gU05NUF9OT1NVQ0hJTlNUQU5DRSkgZ290byBuZXh0OwogICAgICAgICAgICBsZW4gPSB2bHAyLT52YWxfbGVuOwogICAgICAgICAgICBpZiAobGVuID49IFNQUklOVF9NQVhfTEVOKSBsZW4gPSBTUFJJTlRfTUFYX0xFTi0xOwogICAgICAgICAgICBtZW1jcHkoZGVzY3IsIHZscDItPnZhbC5zdHJpbmcsIGxlbik7CiAgICAgICAgICAgIGRlc2NyW2xlbl0gPSAnXDAnOwoKICAgICAgICAgICAgdmxwMiA9IHZscDItPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgIGlmICh2bHAyLT50eXBlID09IFNOTVBfTk9TVUNISU5TVEFOQ0UpIGdvdG8gbmV4dDsKICAgICAgICAgICAgdW5pdHMgPSB2bHAyLT52YWwuaW50ZWdlciA/ICoodmxwMi0+dmFsLmludGVnZXIpIDogMDsKCiAgICAgICAgICAgIHZscDIgPSB2bHAyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICBpZiAodmxwMi0+dHlwZSA9PSBTTk1QX05PU1VDSElOU1RBTkNFKSBnb3RvIG5leHQ7CiAgICAgICAgICAgIGhzc2l6ZSA9IHZscDItPnZhbC5pbnRlZ2VyID8gKih2bHAyLT52YWwuaW50ZWdlcikgOiAwOwoKICAgICAgICAgICAgdmxwMiA9IHZscDItPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgIGlmICh2bHAyLT50eXBlID09IFNOTVBfTk9TVUNISU5TVEFOQ0UpIGdvdG8gbmV4dDsKICAgICAgICAgICAgaHN1c2VkID0gdmxwMi0+dmFsLmludGVnZXIgPyAqKHZscDItPnZhbC5pbnRlZ2VyKSA6IDA7CgogICAgICAgICAgICBwcmludGYoIiUtMThzICUxNWx1ICUxNWx1ICUxNWx1ICU0bHUlJVxuIiwgZGVzY3IsCiAgICAgICAgICAgICAgICAgICB1bml0cyA/IGNvbnZlcnRfdW5pdHMoaHNzaXplLCB1bml0cywgMTAyNCkgOiBoc3NpemUsCiAgICAgICAgICAgICAgICAgICB1bml0cyA/IGNvbnZlcnRfdW5pdHMoaHN1c2VkLCB1bml0cywgMTAyNCkgOiBoc3VzZWQsCiAgICAgICAgICAgICAgICAgICB1bml0cyA/IGNvbnZlcnRfdW5pdHMoaHNzaXplLWhzdXNlZCwgdW5pdHMsIDEwMjQpIDogaHNzaXplIC0KICAgICAgICAgICAgICAgICAgIGhzdXNlZCwgaHNzaXplID8gY29udmVydF91bml0cyhoc3VzZWQsIDEwMCwgaHNzaXplKSA6CiAgICAgICAgICAgICAgICAgICBoc3VzZWQpOwoKICAgICAgICBuZXh0OgogICAgICAgICAgICB2bHAgPSB2bHAtPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgIHNubXBfZnJlZV9wZHUocmVzcG9uc2UpOwogICAgICAgICAgICBjb3VudCsrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY291bnQgPT0gMCkgewogICAgICAgIHNpemVfdCAgICAgICAgICB1bml0cyA9IDA7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGUgaG9zdCByZXNvdXJjZXMgbWliIG11c3Qgbm90IGJlIHN1cHBvcnRlZC4gIExldHMgdHJ5IHRoZQogICAgICAgICAqIFVDRC1TTk1QLU1JQiBhbmQgaXRzIGRza1RhYmxlIAogICAgICAgICAqLwoKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfR0VUTkVYVCk7CiAgICAgICAgYmFzZV9sZW5ndGggPSBhZGQocGR1LCAiVUNELVNOTVAtTUlCOmRza0luZGV4IiwgTlVMTCwgMCk7CiAgICAgICAgbWVtY3B5KGJhc2UsIHBkdS0+dmFyaWFibGVzLT5uYW1lLCBiYXNlX2xlbmd0aCAqIHNpemVvZihvaWQpKTsKCiAgICAgICAgdmxwID0gY29sbGVjdChzcywgcGR1LCBiYXNlLCBiYXNlX2xlbmd0aCk7CgogICAgICAgIHdoaWxlICh2bHApIHsKICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAgIGhzc2l6ZSwgaHN1c2VkOwogICAgICAgICAgICBjaGFyICAgICAgICAgICAgZGVzY3JbU1BSSU5UX01BWF9MRU5dOwogICAgICAgICAgICBpbnQgICAgICAgICAgICAgbGVuOwoKICAgICAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKFNOTVBfTVNHX0dFVCk7CgogICAgICAgICAgICBhZGQocGR1LCAiVUNELVNOTVAtTUlCOmRza1BhdGgiLAogICAgICAgICAgICAgICAgJih2bHAtPm5hbWVbYmFzZV9sZW5ndGhdKSwgdmxwLT5uYW1lX2xlbmd0aCAtIGJhc2VfbGVuZ3RoKTsKICAgICAgICAgICAgYWRkKHBkdSwgIlVDRC1TTk1QLU1JQjpkc2tUb3RhbCIsCiAgICAgICAgICAgICAgICAmKHZscC0+bmFtZVtiYXNlX2xlbmd0aF0pLCB2bHAtPm5hbWVfbGVuZ3RoIC0gYmFzZV9sZW5ndGgpOwogICAgICAgICAgICBhZGQocGR1LCAiVUNELVNOTVAtTUlCOmRza1VzZWQiLAogICAgICAgICAgICAgICAgJih2bHAtPm5hbWVbYmFzZV9sZW5ndGhdKSwgdmxwLT5uYW1lX2xlbmd0aCAtIGJhc2VfbGVuZ3RoKTsKCiAgICAgICAgICAgIHN0YXR1cyA9IHNubXBfc3luY2hfcmVzcG9uc2Uoc3MsIHBkdSwgJnJlc3BvbnNlKTsKICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSBTVEFUX1NVQ0NFU1MgfHwgIXJlc3BvbnNlKSB7CiAgICAgICAgICAgICAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wZGYiLCBzcyk7CiAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2bHAyID0gcmVzcG9uc2UtPnZhcmlhYmxlczsKICAgICAgICAgICAgaWYgKHZscDItPnR5cGUgPT0gU05NUF9OT1NVQ0hJTlNUQU5DRSkgZ290byBuZXh0MjsKICAgICAgICAgICAgbGVuID0gdmxwMi0+dmFsX2xlbjsKICAgICAgICAgICAgaWYgKGxlbiA+PSBTUFJJTlRfTUFYX0xFTikgbGVuID0gU1BSSU5UX01BWF9MRU4tMTsKICAgICAgICAgICAgbWVtY3B5KGRlc2NyLCB2bHAyLT52YWwuc3RyaW5nLCBsZW4pOwogICAgICAgICAgICBkZXNjcltsZW5dID0gJ1wwJzsKCiAgICAgICAgICAgIHZscDIgPSB2bHAyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICBpZiAodmxwMi0+dHlwZSA9PSBTTk1QX05PU1VDSElOU1RBTkNFKSBnb3RvIG5leHQyOwogICAgICAgICAgICBoc3NpemUgPSAqKHZscDItPnZhbC5pbnRlZ2VyKTsKCiAgICAgICAgICAgIHZscDIgPSB2bHAyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICBpZiAodmxwMi0+dHlwZSA9PSBTTk1QX05PU1VDSElOU1RBTkNFKSBnb3RvIG5leHQyOwogICAgICAgICAgICBoc3VzZWQgPSAqKHZscDItPnZhbC5pbnRlZ2VyKTsKCiAgICAgICAgICAgIHByaW50ZigiJS0xOHMgJTE1bHUgJTE1bHUgJTE1bHUgJTRsdSUlXG4iLCBkZXNjciwKICAgICAgICAgICAgICAgICAgIHVuaXRzID8gY29udmVydF91bml0cyhoc3NpemUsIHVuaXRzLCAxMDI0KSA6IGhzc2l6ZSwKICAgICAgICAgICAgICAgICAgIHVuaXRzID8gY29udmVydF91bml0cyhoc3VzZWQsIHVuaXRzLCAxMDI0KSA6IGhzdXNlZCwKICAgICAgICAgICAgICAgICAgIHVuaXRzID8gY29udmVydF91bml0cyhoc3NpemUtaHN1c2VkLCB1bml0cywgMTAyNCkgOiBoc3NpemUgLQogICAgICAgICAgICAgICAgICAgaHN1c2VkLCBoc3NpemUgPyBjb252ZXJ0X3VuaXRzKGhzdXNlZCwgMTAwLCBoc3NpemUpIDoKICAgICAgICAgICAgICAgICAgIGhzdXNlZCk7CgogICAgICAgIG5leHQyOgogICAgICAgICAgICB2bHAgPSB2bHAtPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgIHNubXBfZnJlZV9wZHUocmVzcG9uc2UpOwogICAgICAgICAgICBjb3VudCsrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY291bnQgPT0gMCkgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiRmFpbGVkIHRvIGxvY2F0ZSBhbnkgcGFydGl0aW9ucy5cbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgogICAgc25tcF9jbG9zZShzcyk7CiAgICBTT0NLX0NMRUFOVVA7CiAgICByZXR1cm4gMDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIG1haW4oKSAqLwo=