LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCioKKiAgIENvcHlyaWdodCAoQykgMTk5OS0yMDAzLCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzCiogICBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKgogKiB1Y29udigxKTogYW4gaWNvbnYoMSktbGlrZSBjb252ZXJ0ZXIgdXNpbmcgSUNVLgogKgogKiBPcmlnaW5hbCBjb2RlIGJ5IEpvbmFzIFV0dGVyc3Ry9m0gPGpvbmFzLnV0dGVyc3Ryb21Adml0dHJhbi5ub3Jybm9kLnNlPgogKiBjb250cmlidXRlZCBpbiAxOTk5LgogKgogKiBDb252ZXJzaW9uIHRvIHRoZSBDIGNvbnZlcnNpb24gQVBJIGFuZCBtYW55IGltcHJvdmVtZW50cyBieQogKiBZdmVzIEFycm91eWUgPHl2ZXNAcmVhbG5hbWVzLmNvbT4sIGN1cnJlbnQgbWFpbnRhaW5lci4KICoKICogTWFya3VzIFNjaGVyZXIgbWFpbnRhaW5lciBmcm9tIDIwMDMuCiAqIFNlZSBzb3VyY2UgY29kZSByZXBvc2l0b3J5IGhpc3RvcnkgZm9yIGNoYW5nZXMuCiAqLwoKI2luY2x1ZGUgPHVuaWNvZGUvdXR5cGVzLmg+CiNpbmNsdWRlIDx1bmljb2RlL3VjbnYuaD4KI2luY2x1ZGUgPHVuaWNvZGUvdWVudW0uaD4KI2luY2x1ZGUgPHVuaWNvZGUvdW5pc3RyLmg+CiNpbmNsdWRlIDx1bmljb2RlL3RyYW5zbGl0Lmg+CiNpbmNsdWRlIDx1bmljb2RlL3VzZXQuaD4KI2luY2x1ZGUgPHVuaWNvZGUvdWNsZWFuLmg+CgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgoKI2luY2x1ZGUgImNtZW1vcnkuaCIKI2luY2x1ZGUgImNzdHJpbmcuaCIKI2luY2x1ZGUgInVzdHJmbXQuaCIKCiNpbmNsdWRlICJ1bmljb2RlL3V3bXNnLmgiCgojaWYgZGVmaW5lZChXSU4zMikgfHwgZGVmaW5lZChVX0NZR1dJTikKI2luY2x1ZGUgPGlvLmg+CiNpbmNsdWRlIDxmY250bC5oPgojZW5kaWYKCiNpZmRlZiBVQ09OVk1TR19MSU5LCi8qIGJlbG93IGZyb20gdGhlIFJFQURNRSAqLwojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvdWRhdGEuaCIKVV9DRlVOQyBjaGFyIHVjb252bXNnX2RhdFtdOwojZW5kaWYKCiNkZWZpbmUgTEVOR1RIT0YoYXJyYXkpIChpbnQzMl90KShzaXplb2YoYXJyYXkpL3NpemVvZigoYXJyYXkpWzBdKSkKCiNkZWZpbmUgREVGQVVMVF9CVUZTWiAgIDQwOTYKI2RlZmluZSBVQ09OVk1TRyAidWNvbnZtc2ciCgpzdGF0aWMgVVJlc291cmNlQnVuZGxlICpnQnVuZGxlID0gMDsgICAgLyogQnVuZGxlIGNvbnRhaW5pbmcgbWVzc2FnZXMuICovCgovKgogKiBJbml0aWFsaXplIHRoZSBtZXNzYWdlIGJ1bmRsZSBzbyB0aGF0IG1lc3NhZ2Ugc3RyaW5ncyBjYW4gYmUgZmV0Y2hlZAogKiBieSB1X3dtc2coKS4KICoKICovCgpzdGF0aWMgdm9pZCBpbml0TXNnKGNvbnN0IGNoYXIgKnBuYW1lKSB7CiAgICBzdGF0aWMgaW50IHBzID0gMDsKCiAgICBpZiAoIXBzKSB7CiAgICAgICAgY2hhciBkYXRhUGF0aFsyMDQ4XTsgICAgICAgIC8qIFhYWCBTbG9wcHk6IHNob3VsZCBiZSBQQVRIX01BWC4gKi8KICAgICAgICBVRXJyb3JDb2RlIGVyciA9IFVfWkVST19FUlJPUjsKCiAgICAgICAgcHMgPSAxOwoKICAgICAgICAvKiBTZXQgdXAgb3VyIHN0YXRpYyBkYXRhIC0gaWYgYW55ICovCiNpZmRlZiBVQ09OVk1TR19MSU5LCiAgICAgICAgdWRhdGFfc2V0QXBwRGF0YShVQ09OVk1TRywgKGNvbnN0IHZvaWQqKSB1Y29udm1zZ19kYXQsICZlcnIpOwogICAgICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgICAgZnByaW50ZihzdGRlcnIsICIlczogd2FybmluZywgcHJvYmxlbSBpbnN0YWxsaW5nIG91ciBzdGF0aWMgcmVzb3VyY2UgYnVuZGxlIGRhdGEgdWNvbnZtc2c6ICVzIC0gdHJ5aW5nIGFueXdheXMuXG4iLAogICAgICAgICAgICAgICAgICBwbmFtZSwgdV9lcnJvck5hbWUoZXJyKSk7CiAgICAgICAgICBlcnIgPSBVX1pFUk9fRVJST1I7IC8qIEl0IG1heSBzdGlsbCBmYWlsICovCiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgLyogR2V0IG1lc3NhZ2VzLiAqLwogICAgICAgIGdCdW5kbGUgPSB1X3dtc2dfc2V0UGF0aChVQ09OVk1TRywgJmVycik7CiAgICAgICAgaWYgKFVfRkFJTFVSRShlcnIpKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAgICAgICAgICIlczogd2FybmluZzogY291bGRuJ3Qgb3BlbiBidW5kbGUgJXM6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgIHBuYW1lLCBVQ09OVk1TRywgdV9lcnJvck5hbWUoZXJyKSk7CiNpZmRlZiBVQ09OVk1TR19MSU5LCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAgICAgICAgICIlczogc2V0QXBwRGF0YSB3YXMgY2FsbGVkLCBpbnRlcm5hbCBkYXRhICVzIGZhaWxlZCB0byBsb2FkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBwbmFtZSwgVUNPTlZNU0cpOwojZW5kaWYKIAogICAgICAgICAgICBlcnIgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgICAgIC8qIHRoYXQgd2FzIHRyeSAjMSwgdHJ5IGFnYWluIHdpdGggYSBwYXRoICovCiAgICAgICAgICAgIHVwcnZfc3RyY3B5KGRhdGFQYXRoLCB1X2dldERhdGFEaXJlY3RvcnkoKSk7CiAgICAgICAgICAgIHVwcnZfc3RyY2F0KGRhdGFQYXRoLCBVX0ZJTEVfU0VQX1NUUklORyk7CiAgICAgICAgICAgIHVwcnZfc3RyY2F0KGRhdGFQYXRoLCBVQ09OVk1TRyk7CgogICAgICAgICAgICBnQnVuZGxlID0gdV93bXNnX3NldFBhdGgoZGF0YVBhdGgsICZlcnIpOwogICAgICAgICAgICBpZiAoVV9GQUlMVVJFKGVycikpIHsKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAgICAgICAgICIlczogd2FybmluZzogc3RpbGwgY291bGRuJ3Qgb3BlbiBidW5kbGUgJXM6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgIHBuYW1lLCBkYXRhUGF0aCwgdV9lcnJvck5hbWUoZXJyKSk7CiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIiVzOiB3YXJuaW5nOiBtZXNzYWdlcyB3aWxsIG5vdCBiZSBkaXNwbGF5ZWRcbiIsIHBuYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKLyogTWFwcGluZyBvZiBjYWxsYmFjayBuYW1lcyB0byB0aGUgY2FsbGJhY2tzIHBhc3NlZCB0byB0aGUgY29udmVydGVyCiAgIEFQSS4gKi8KCnN0YXRpYyBzdHJ1Y3QgY2FsbGJhY2tfZW50IHsKICAgIGNvbnN0IGNoYXIgKm5hbWU7CiAgICBVQ29udmVydGVyRnJvbVVDYWxsYmFjayBmcm9tdTsKICAgIGNvbnN0IHZvaWQgKmZyb211Y3R4dDsKICAgIFVDb252ZXJ0ZXJUb1VDYWxsYmFjayB0b3U7CiAgICBjb25zdCB2b2lkICp0b3VjdHh0Owp9IHRyYW5zY29kZV9jYWxsYmFja3NbXSA9IHsKICAgIHsgInN1YnN0aXR1dGUiLAogICAgICBVQ05WX0ZST01fVV9DQUxMQkFDS19TVUJTVElUVVRFLCAwLAogICAgICBVQ05WX1RPX1VfQ0FMTEJBQ0tfU1VCU1RJVFVURSwgMCB9LAogICAgeyAic2tpcCIsCiAgICAgIFVDTlZfRlJPTV9VX0NBTExCQUNLX1NLSVAsIDAsCiAgICAgIFVDTlZfVE9fVV9DQUxMQkFDS19TS0lQLCAwIH0sCiAgICB7ICJzdG9wIiwKICAgICAgVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfU1RPUCwgMCwKICAgICAgVUNOVl9UT19VX0NBTExCQUNLX1NUT1AsIDAgfSwKICAgIHsgImVzY2FwZSIsCiAgICAgIFVDTlZfRlJPTV9VX0NBTExCQUNLX0VTQ0FQRSwgMCwKICAgICAgVUNOVl9UT19VX0NBTExCQUNLX0VTQ0FQRSwgMH0sCiAgICB7ICJlc2NhcGUtaWN1IiwKICAgICAgVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfRVNDQVBFLCBVQ05WX0VTQ0FQRV9JQ1UsCiAgICAgIFVDTlZfVE9fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX0lDVSB9LAogICAgeyAiZXNjYXBlLWphdmEiLAogICAgICBVQ05WX0ZST01fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX0pBVkEsCiAgICAgIFVDTlZfVE9fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX0pBVkEgfSwKICAgIHsgImVzY2FwZS1jIiwKICAgICAgVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfRVNDQVBFLCBVQ05WX0VTQ0FQRV9DLAogICAgICBVQ05WX1RPX1VfQ0FMTEJBQ0tfRVNDQVBFLCBVQ05WX0VTQ0FQRV9DIH0sCiAgICB7ICJlc2NhcGUteG1sIiwKICAgICAgVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfRVNDQVBFLCBVQ05WX0VTQ0FQRV9YTUxfSEVYLAogICAgICBVQ05WX1RPX1VfQ0FMTEJBQ0tfRVNDQVBFLCBVQ05WX0VTQ0FQRV9YTUxfSEVYIH0sCiAgICB7ICJlc2NhcGUteG1sLWhleCIsCiAgICAgIFVDTlZfRlJPTV9VX0NBTExCQUNLX0VTQ0FQRSwgVUNOVl9FU0NBUEVfWE1MX0hFWCwKICAgICAgVUNOVl9UT19VX0NBTExCQUNLX0VTQ0FQRSwgVUNOVl9FU0NBUEVfWE1MX0hFWCB9LAogICAgeyAiZXNjYXBlLXhtbC1kZWMiLAogICAgICBVQ05WX0ZST01fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX1hNTF9ERUMsCiAgICAgIFVDTlZfVE9fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX1hNTF9ERUMgfSwKICAgIHsgImVzY2FwZS11bmljb2RlIiwgVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfRVNDQVBFLCBVQ05WX0VTQ0FQRV9VTklDT0RFLAogICAgICBVQ05WX1RPX1VfQ0FMTEJBQ0tfRVNDQVBFLCBVQ05WX0VTQ0FQRV9VTklDT0RFIH0KfTsKCi8qIFJldHVybiBhIHBvaW50ZXIgdG8gYSBjYWxsYmFjayByZWNvcmQgZ2l2ZW4gaXRzIG5hbWUuICovCgpzdGF0aWMgY29uc3Qgc3RydWN0IGNhbGxiYWNrX2VudCAqZmluZENhbGxiYWNrKGNvbnN0IGNoYXIgKm5hbWUpIHsKICAgIGludCBpLCBjb3VudCA9CiAgICAgICAgc2l6ZW9mKHRyYW5zY29kZV9jYWxsYmFja3MpIC8gc2l6ZW9mKCp0cmFuc2NvZGVfY2FsbGJhY2tzKTsKCiAgICAvKiBXZSdsbCBkbyBhIGxpbmVhciBzZWFyY2gsIHRoZXJlIGFyZW4ndCBtYW55IG9mIHRoZW0gYW5kIGJzZWFyY2goKQogICAgICAgbWF5IG5vdCBiZSB0aGF0IHBvcnRhYmxlLiAqLwoKICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CiAgICAgICAgaWYgKCF1cHJ2X3N0cmljbXAobmFtZSwgdHJhbnNjb2RlX2NhbGxiYWNrc1tpXS5uYW1lKSkgewogICAgICAgICAgICByZXR1cm4gJnRyYW5zY29kZV9jYWxsYmFja3NbaV07CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAwOwp9CgovKiBQcmludCBjb252ZXJ0ZXIgaW5mb3JtYXRpb24uIElmIGxvb2tmb3IgaXMgc2V0LCBvbmx5IHRoYXQgY29udmVydGVyIHdpbGwKICAgYmUgcHJpbnRlZCwgb3RoZXJ3aXNlIGFsbCBjb252ZXJ0ZXJzIHdpbGwgYmUgcHJpbnRlZC4gSWYgY2Fub24gaXMgbm9uCiAgIHplcm8sIHRhZ3MgYW5kIGFsaWFzZXMgZm9yIGVhY2ggY29udmVydGVyIGFyZSBwcmludGVkIHRvbywgaW4gdGhlIGZvcm1hdAogICBleHBlY3RlZCBmb3IgY29udnJ0ZXJzLnR4dCg1KS4gKi8KCnN0YXRpYyBpbnQgcHJpbnRDb252ZXJ0ZXJzKGNvbnN0IGNoYXIgKnBuYW1lLCBjb25zdCBjaGFyICpsb29rZm9yLAogICAgVUJvb2wgY2Fub24pCnsKICAgIFVFcnJvckNvZGUgZXJyID0gVV9aRVJPX0VSUk9SOwogICAgaW50MzJfdCBudW07CiAgICB1aW50MTZfdCBudW1fc3RkczsKICAgIGNvbnN0IGNoYXIgKipzdGRzOwoKICAgIC8qIElmIHRoZXJlIGlzIGEgc3BlY2lmaWVkIG5hbWUsIGp1c3QgaGFuZGxlIHRoYXQgbm93LiAqLwoKICAgIGlmIChsb29rZm9yKSB7CiAgICAgICAgaWYgKCFjYW5vbikgewogICAgICAgICAgICBwcmludGYoIiVzXG4iLCBsb29rZm9yKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAvKiAgQmVjYXVzZSB3ZSBhcmUgcHJpbnRpbmcgYSBjYW5vbmljYWwgbmFtZSwgd2UgbmVlZCB0aGUKICAgICAgICAgICAgdHJ1ZSBjb252ZXJ0ZXIgbmFtZS4gV2UndmUgZG9uZSB0aGF0IGFscmVhZHkgZXhjZXB0IGZvcgogICAgICAgICAgICB0aGUgZGVmYXVsdCBuYW1lIChiZWNhdXNlIHdlIHdhbnQgdG8gcHJpbnQgdGhlIGV4YWN0CiAgICAgICAgICAgIG5hbWUgb25lIHdvdWxkIGdldCB3aGVuIGNhbGxpbmcgdWNudl9nZXREZWZhdWx0TmFtZSgpCiAgICAgICAgICAgIGluIG5vbi1jYW5vbiBtb2RlKS4gQnV0IHNpbmNlIHdlIGRvIG5vdCBrbm93IGF0IHRoaXMKICAgICAgICAgICAgcG9pbnQgaWYgd2UgaGF2ZSB0aGUgZGVmYXVsdCBuYW1lIG9yIHNvbWV0aGluZyBlbHNlLCB3ZQogICAgICAgICAgICBuZWVkIHRvIG5vcm1hbGl6ZSBhZ2FpbiB0byB0aGUgY2Fub25pY2FsIGNvbnZlcnRlcgogICAgICAgICAgICBuYW1lLiAqLwoKICAgICAgICAgICAgY29uc3QgY2hhciAqdHJ1ZW5hbWUgPSB1Y252X2dldEFsaWFzKGxvb2tmb3IsIDAsICZlcnIpOwogICAgICAgICAgICBpZiAoVV9TVUNDRVNTKGVycikpIHsKICAgICAgICAgICAgICAgIGxvb2tmb3IgPSB0cnVlbmFtZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVyciA9IFVfWkVST19FUlJPUjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBQcmludCBjb252ZXJ0ZXIgbmFtZXMuIFdlIGNvbWUgaGVyZSBmb3Igb25lIG9mIHR3byByZWFzb25zOiB3ZQogICAgICAgYXJlIHByaW50aW5nIGFsbCB0aGUgbmFtZXMgKGxvb2tmb3Igd2FzIG51bGwpLCBvciB3ZSBoYXZlIGEKICAgICAgIHNpbmdsZSBjb252ZXJ0ZXIgdG8gcHJpbnQgYnV0IGluIGNhbm9uIG1vZGUsIGhlbmNlIHdlIG5lZWQgdG8KICAgICAgIGdldCB0byBpdCBpbiBvcmRlciB0byBwcmludCBldmVyeXRoaW5nLiAqLwoKICAgIG51bSA9IHVjbnZfY291bnRBdmFpbGFibGUoKTsKICAgIGlmIChudW0gPD0gMCkgewogICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50R2V0TmFtZXMiKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBpZiAobG9va2ZvcikgewogICAgICAgIG51bSA9IDE7ICAgICAgICAgICAgICAgIC8qIFdlIGtub3cgd2hlcmUgd2Ugd2FudCB0byBiZS4gKi8KICAgIH0KCiAgICBudW1fc3RkcyA9IHVjbnZfY291bnRTdGFuZGFyZHMoKTsKICAgIHN0ZHMgPSAoY29uc3QgY2hhciAqKikgdXBydl9tYWxsb2MobnVtX3N0ZHMgKiBzaXplb2YoKnN0ZHMpKTsKICAgIGlmICghc3RkcykgewogICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50R2V0VGFnIiwgdV93bXNnX2Vycm9yTmFtZShVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKSk7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfSBlbHNlIHsKICAgICAgICB1aW50MTZfdCBzOwoKICAgICAgICBpZiAoY2Fub24pIHsKICAgICAgICAgICAgcHJpbnRmKCJ7ICIpOwogICAgICAgIH0KICAgICAgICBmb3IgKHMgPSAwOyBzIDwgbnVtX3N0ZHM7ICsrcykgewogICAgICAgICAgICBzdGRzW3NdID0gdWNudl9nZXRTdGFuZGFyZChzLCAmZXJyKTsKICAgICAgICAgICAgaWYgKGNhbm9uKSB7CiAgICAgICAgICAgICAgICBwcmludGYoIiVzICIsIHN0ZHNbc10pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRHZXRUYWciLCB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChjYW5vbikgewogICAgICAgICAgICBwdXRzKCJ9Iik7CiAgICAgICAgfQogICAgfQoKICAgIGZvciAoaW50MzJfdCBpID0gMDsgaSA8IG51bTsgaSsrKSB7CiAgICAgICAgY29uc3QgY2hhciAqbmFtZTsKICAgICAgICB1aW50MTZfdCBudW1fYWxpYXNlczsKCiAgICAgICAgLyogU2V0IHRoZSBuYW1lIGVpdGhlciB0byB3aGF0IHdlIGFyZSBsb29raW5nIGZvciwgb3IKICAgICAgICB0byB0aGUgY3VycmVudCBjb252ZXJ0ZXIgbmFtZS4gKi8KCiAgICAgICAgaWYgKGxvb2tmb3IpIHsKICAgICAgICAgICAgbmFtZSA9IGxvb2tmb3I7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmFtZSA9IHVjbnZfZ2V0QXZhaWxhYmxlTmFtZShpKTsKICAgICAgICB9CgogICAgICAgIC8qIEdldCBhbGwgdGhlIGFsaWFzZXMgYXNzb2NpYXRlZCB0byB0aGUgbmFtZS4gKi8KCiAgICAgICAgZXJyID0gVV9aRVJPX0VSUk9SOwogICAgICAgIG51bV9hbGlhc2VzID0gdWNudl9jb3VudEFsaWFzZXMobmFtZSwgJmVycik7CiAgICAgICAgaWYgKFVfRkFJTFVSRShlcnIpKSB7CiAgICAgICAgICAgIHByaW50ZigiJXMiLCBuYW1lKTsKCiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKG5hbWUsICIiKTsKICAgICAgICAgICAgcHV0Y2hhcignXHQnKTsKICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRHZXRBbGlhc2VzIiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSwKICAgICAgICAgICAgICAgIHVfd21zZ19lcnJvck5hbWUoZXJyKSk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB1aW50MTZfdCBhLCBzLCB0OwoKICAgICAgICAgICAgLyogV3JpdGUgYWxsIHRoZSBhbGlhc2VzIGFuZCB0aGVpciB0YWdzLiAqLwoKICAgICAgICAgICAgZm9yIChhID0gMDsgYSA8IG51bV9hbGlhc2VzOyArK2EpIHsKICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmFsaWFzID0gdWNudl9nZXRBbGlhcyhuYW1lLCBhLCAmZXJyKTsKCiAgICAgICAgICAgICAgICBpZiAoVV9GQUlMVVJFKGVycikpIHsKICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cihuYW1lLCAiIik7CiAgICAgICAgICAgICAgICAgICAgcHV0Y2hhcignXHQnKTsKICAgICAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudEdldEFsaWFzZXMiLCBzdHIuZ2V0VGVybWluYXRlZEJ1ZmZlcigpLAogICAgICAgICAgICAgICAgICAgICAgICB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBQcmludCB0aGUgY3VycmVudCBhbGlhcyBzbyB0aGF0IGl0IGxvb2tzIHJpZ2h0LiAqLwogICAgICAgICAgICAgICAgcHJpbnRmKCIlcyVzJXMiLCAoY2Fub24gPyAoYSA9PSAwPyAiIiA6ICJcdCIgKSA6ICIiKSAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWFzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2Fub24gPyAiIiA6ICIgIikpOwoKICAgICAgICAgICAgICAgIC8qIExvb2sgKHNsb3dseSwgbGluZWFyIHNlYXJjaGluZykgZm9yIGEgdGFnLiAqLwoKICAgICAgICAgICAgICAgIGlmIChjYW5vbikgewogICAgICAgICAgICAgICAgICAgIC8qIC0xIHRvIHNraXAgdGhlIGxhc3Qgc3RhbmRhcmQgKi8KICAgICAgICAgICAgICAgICAgICBmb3IgKHMgPSB0ID0gMDsgcyA8IG51bV9zdGRzLTE7ICsrcykgewogICAgICAgICAgICAgICAgICAgICAgICBVRW51bWVyYXRpb24gKm5hbWVFbnVtID0gdWNudl9vcGVuU3RhbmRhcmROYW1lcyhuYW1lLCBzdGRzW3NdLCAmZXJyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFVfU1VDQ0VTUyhlcnIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBMaXN0IHRoZSBzdGFuZGFyZCB0YWdzICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpzdGFuZGFyZE5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCBpc0ZpcnN0ID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgZW51bUVycm9yID0gVV9aRVJPX0VSUk9SOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChzdGFuZGFyZE5hbWUgPSB1ZW51bV9uZXh0KG5hbWVFbnVtLCBOVUxMLCAmZW51bUVycm9yKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBTZWUgaWYgdGhpcyBhbGlhcyBpcyBzdXBwb3J0ZWQgYnkgdGhpcyBzdGFuZGFyZC4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0cmNtcChzdGFuZGFyZE5hbWUsIGFsaWFzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiIHsiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFByaW50IGEgKiBhZnRlciB0aGUgZGVmYXVsdCBzdGFuZGFyZCBuYW1lICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiICVzJXMiLCBzdGRzW3NdLCAoaXNGaXJzdCA/ICIqIiA6ICIiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRmlyc3QgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAodCkgewogICAgICAgICAgICAgICAgICAgICAgICBwcmludGYoIiB9Iik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLyogVGVybWluYXRlIHRoaXMgZW50cnkuICovCiAgICAgICAgICAgICAgICBpZiAoY2Fub24pIHsKICAgICAgICAgICAgICAgICAgICBwdXRzKCIiKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBNb3ZlIG9uLiAqLwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIFRlcm1pbmF0ZSB0aGlzIGVudHJ5LiAqLwogICAgICAgICAgICBpZiAoIWNhbm9uKSB7CiAgICAgICAgICAgICAgICBwdXRzKCIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBGcmVlIHRlbXBvcmFyeSBkYXRhLiAqLwoKICAgIHVwcnZfZnJlZShzdGRzKTsKCiAgICAvKiBTdWNjZXNzLiAqLwoKICAgIHJldHVybiAwOwp9CgovKiBQcmludCBhbGwgYXZhaWxhYmxlIHRyYW5zbGl0ZXJhdG9ycy4gSWYgY2Fub24gaXMgbm9uIHplcm8sIHByaW50CiAgIG9uZSB0cmFuc2xpdGVyYXRvciBwZXIgbGluZS4gKi8KCnN0YXRpYyBpbnQgcHJpbnRUcmFuc2xpdGVyYXRvcnMoVUJvb2wgY2Fub24pCnsKI2lmIFVDT05GSUdfTk9fVFJBTlNMSVRFUkFUSU9OCiAgICBwcmludGYoIm5vIHRyYW5zbGl0ZXJhdG9ycyBhdmFpbGFibGUgYmVjYXVzZSBvZiBVQ09ORklHX05PX1RSQU5TTElURVJBVElPTiwgc2VlIHVjb25maWcuaFxuIik7CiAgICByZXR1cm4gMTsKI2Vsc2UKICAgIGludDMyX3QgbnVtdHJhbnMgPSB1dHJhbnNfY291bnRBdmFpbGFibGVJRHMoKSwgaTsKICAgIGludCBidWZsZW4gPSA1MTI7CiAgICBjaGFyICpidWYgPSAoY2hhciAqKSB1cHJ2X21hbGxvYyhidWZsZW4pOwogICAgY2hhciBzdGF0aWNidWZbNTEyXTsKCiAgICBjaGFyIHNlcGNoYXIgPSBjYW5vbiA/ICdcbicgOiAnICc7CgogICAgaWYgKCFidWYpIHsKICAgICAgICBidWYgPSBzdGF0aWNidWY7CiAgICAgICAgYnVmbGVuID0gc2l6ZW9mKHN0YXRpY2J1Zik7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IG51bXRyYW5zOyArK2kpIHsKICAgICAgICBpbnQzMl90IGxlbiA9IHV0cmFuc19nZXRBdmFpbGFibGVJRChpLCBidWYsIGJ1Zmxlbik7CiAgICAgICAgaWYgKGxlbiA+PSBidWZsZW4gLSAxKSB7CiAgICAgICAgICAgIGlmIChidWYgIT0gc3RhdGljYnVmKSB7CiAgICAgICAgICAgICAgICBidWZsZW4gPDw9IDE7CiAgICAgICAgICAgICAgICBpZiAoYnVmbGVuIDwgbGVuKSB7CiAgICAgICAgICAgICAgICAgICAgYnVmbGVuID0gbGVuICsgNjQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBidWYgPSAoY2hhciAqKSB1cHJ2X3JlYWxsb2MoYnVmLCBidWZsZW4pOwogICAgICAgICAgICAgICAgaWYgKCFidWYpIHsKICAgICAgICAgICAgICAgICAgICBidWYgPSBzdGF0aWNidWY7CiAgICAgICAgICAgICAgICAgICAgYnVmbGVuID0gc2l6ZW9mKHN0YXRpY2J1Zik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdXRyYW5zX2dldEF2YWlsYWJsZUlEKGksIGJ1ZiwgYnVmbGVuKTsKICAgICAgICAgICAgaWYgKGxlbiA+PSBidWZsZW4pIHsKICAgICAgICAgICAgICAgIHVwcnZfc3RyY3B5KGJ1ZiArIGJ1ZmxlbiAtIDQsICIuLi4iKTsgLyogVHJ1bmNhdGUgdGhlIG5hbWUuICovCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaW50ZigiJXMiLCBidWYpOwogICAgICAgIGlmIChpIDwgbnVtdHJhbnMgLSAxKSB7CiAgICAgICAgICAgIHB1dGNoYXIoc2VwY2hhcik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEFkZCBhIHRlcm1pbmF0aW5nIG5ld2xpbmUgaWYgbmVlZGVkLiAqLwoKICAgIGlmIChzZXBjaGFyICE9ICdcbicpIHsKICAgICAgICBwdXRjaGFyKCdcbicpOwogICAgfQoKICAgIC8qIEZyZWUgdGVtcG9yYXJ5IGRhdGEuICovCgogICAgaWYgKGJ1ZiAhPSBzdGF0aWNidWYpIHsKICAgICAgICB1cHJ2X2ZyZWUoYnVmKTsKICAgIH0KCiAgICAvKiBTdWNjZXNzLiAqLwoKICAgIHJldHVybiAwOwojZW5kaWYKfQoKZW51bSB7CiAgICB1U1AgPSAweDIwLCAgICAgICAgIC8vIHNwYWNlCiAgICB1Q1IgPSAweGQsICAgICAgICAgIC8vIGNhcnJpYWdlIHJldHVybgogICAgdUxGID0gMHhhLCAgICAgICAgICAvLyBsaW5lIGZlZWQKICAgIHVOTCA9IDB4ODUsICAgICAgICAgLy8gbmV3bGluZQogICAgdUxTID0gMHgyMDI4LCAgICAgICAvLyBsaW5lIHNlcGFyYXRvcgogICAgdVBTID0gMHgyMDI5LCAgICAgICAvLyBwYXJhZ3JhcGggc2VwYXJhdG9yCiAgICB1U2lnID0gMHhmZWZmICAgICAgIC8vIHNpZ25hdHVyZS9CT00gY2hhcmFjdGVyCn07CgpzdGF0aWMgaW5saW5lIGludDMyX3QKZ2V0Q2h1bmtMaW1pdChjb25zdCBVbmljb2RlU3RyaW5nICZwcmV2LCBjb25zdCBVbmljb2RlU3RyaW5nICZzKSB7CiAgICAvLyBmaW5kIG9uZSBvZgogICAgLy8gQ1IsIExGLCBDUkxGLCBOTCwgTFMsIFBTCiAgICAvLyBmb3IgcGFyYWdyYXBoIGVuZHMgKHNlZSBVQVggIzEzL1VuaWNvZGUgNCkKICAgIC8vIGFuZCBpbmNsdWRlIGl0IGluIHRoZSBjaHVuawogICAgLy8gYWxsIG9mIHRoZXNlIGNoYXJhY3RlcnMgYXJlIG9uIHRoZSBCTVAKICAgIC8vIGRvIG5vdCBpbmNsdWRlIEZGIG9yIFZUIGluIGNhc2UgdGhleSBhcmUgcGFydCBvZiBhIHBhcmFncmFwaAogICAgLy8gKGltcG9ydGFudCBmb3IgYmlkaSBjb250ZXh0cykKICAgIHN0YXRpYyBjb25zdCBVQ2hhciBwYXJhRW5kc1tdID0gewogICAgICAgIDB4ZCwgMHhhLCAweDg1LCAweDIwMjgsIDB4MjAyOQogICAgfTsKICAgIGVudW0gewogICAgICAgIGlDUiwgaUxGLCBpTkwsIGlMUywgaVBTLCBpQ291bnQKICAgIH07CgogICAgLy8gZmlyc3QsIHNlZSBpZiB0aGVyZSBpcyBhIENSTEYgc3BsaXQgYmV0d2VlbiBwcmV2IGFuZCBzCiAgICBpZiAocHJldi5lbmRzV2l0aChwYXJhRW5kcyArIGlDUiwgMSkpIHsKICAgICAgICBpZiAocy5zdGFydHNXaXRoKHBhcmFFbmRzICsgaUxGLCAxKSkgewogICAgICAgICAgICByZXR1cm4gMTsgLy8gc3BsaXQgQ1JMRiwgaW5jbHVkZSB0aGUgTEYKICAgICAgICB9IGVsc2UgaWYgKCFzLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXR1cm4gMDsgLy8gY29tcGxldGUgdGhlIGxhc3QgY2h1bmsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gLTE7IC8vIHdhaXQgZm9yIGFjdHVhbCBmdXJ0aGVyIGNvbnRlbnRzIHRvIGFycml2ZQogICAgICAgIH0KICAgIH0KCiAgICBjb25zdCBVQ2hhciAqdSA9IHMuZ2V0QnVmZmVyKCksICpsaW1pdCA9IHUgKyBzLmxlbmd0aCgpOwogICAgVUNoYXIgYzsKCiAgICB3aGlsZSAodSA8IGxpbWl0KSB7CiAgICAgICAgYyA9ICp1Kys7CiAgICAgICAgaWYgKAogICAgICAgICAgICAoKGMgPCB1U1ApICYmIChjID09IHVDUiB8fCBjID09IHVMRikpIHx8CiAgICAgICAgICAgIChjID09IHVOTCkgfHwKICAgICAgICAgICAgKChjICYgdUxTKSA9PSB1TFMpCiAgICAgICAgKSB7CiAgICAgICAgICAgIGlmIChjID09IHVDUikgewogICAgICAgICAgICAgICAgLy8gY2hlY2sgZm9yIENSTEYKICAgICAgICAgICAgICAgIGlmICh1ID09IGxpbWl0KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOyAvLyBMRiBtYXkgYmUgaW4gdGhlIG5leHQgY2h1bmsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKnUgPT0gdUxGKSB7CiAgICAgICAgICAgICAgICAgICAgKyt1OyAvLyBpbmNsdWRlIHRoZSBMRiBpbiB0aGlzIGNodW5rCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIChpbnQzMl90KSh1IC0gcy5nZXRCdWZmZXIoKSk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAtMTsgLy8gY29udGludWUgY29sbGVjdGluZyB0aGUgY2h1bmsKfQoKZW51bSB7CiAgICBDTlZfTk9fRkVGRiwgICAgLy8gY2Fubm90IGNvbnZlcnQgdGhlIFUrRkVGRiBVbmljb2RlIHNpZ25hdHVyZSBjaGFyYWN0ZXIgKEJPTSkKICAgIENOVl9XSVRIX0ZFRkYsICAvLyBjYW4gY29udmVydCB0aGUgVStGRUZGIHNpZ25hdHVyZSBjaGFyYWN0ZXIKICAgIENOVl9BRERTX0ZFRkYgICAvLyBhdXRvbWF0aWNhbGx5IGFkZHMvZGV0ZWN0cyB0aGUgVStGRUZGIHNpZ25hdHVyZSBjaGFyYWN0ZXIKfTsKCnN0YXRpYyBpbmxpbmUgVUNoYXIKbmliYmxlVG9IZXgodWludDhfdCBuKSB7CiAgICBuICY9IDB4ZjsKICAgIHJldHVybgogICAgICAgIG4gPD0gOSA/CiAgICAgICAgICAgIChVQ2hhcikoMHgzMCArIG4pIDoKICAgICAgICAgICAgKFVDaGFyKSgoMHg2MSAtIDEwKSArIG4pOwp9CgovLyBjaGVjayB0aGUgY29udmVydGVyJ3MgVW5pY29kZSBzaWduYXR1cmUgcHJvcGVydGllczsKLy8gdGhlIGZyb21Vbmljb2RlIHNpZGUgb2YgdGhlIGNvbnZlcnRlciBtdXN0IGJlIGluIGl0cyBpbml0aWFsIHN0YXRlCi8vIGFuZCB3aWxsIGJlIHJlc2V0IGFnYWluIGlmIGl0IHdhcyB1c2VkCnN0YXRpYyBpbnQzMl90CmNudlNpZ1R5cGUoVUNvbnZlcnRlciAqY252KSB7CiAgICBVRXJyb3JDb2RlIGVycjsKICAgIGludDMyX3QgcmVzdWx0OwoKICAgIC8vIHRlc3QgaWYgdGhlIG91dHB1dCBjaGFyc2V0IGNhbiBjb252ZXJ0IFUrRkVGRgogICAgVVNldCAqc2V0ID0gdXNldF9vcGVuKDEsIDApOwogICAgZXJyID0gVV9aRVJPX0VSUk9SOwogICAgdWNudl9nZXRVbmljb2RlU2V0KGNudiwgc2V0LCBVQ05WX1JPVU5EVFJJUF9TRVQsICZlcnIpOwogICAgaWYgKFVfU1VDQ0VTUyhlcnIpICYmIHVzZXRfY29udGFpbnMoc2V0LCB1U2lnKSkgewogICAgICAgIHJlc3VsdCA9IENOVl9XSVRIX0ZFRkY7CiAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdCA9IENOVl9OT19GRUZGOyAvLyBhbiBlcnJvciBvY2N1cnJlZCBvciBVK0ZFRkYgY2Fubm90IGJlIGNvbnZlcnRlZAogICAgfQogICAgdXNldF9jbG9zZShzZXQpOwoKICAgIGlmIChyZXN1bHQgPT0gQ05WX1dJVEhfRkVGRikgewogICAgICAgIC8vIHRlc3QgaWYgdGhlIG91dHB1dCBjaGFyc2V0IGVtaXRzIGEgc2lnbmF0dXJlIGFueXdheQogICAgICAgIGNvbnN0IFVDaGFyIGFbMV0gPSB7IDB4NjEgfTsgLy8gImEiCiAgICAgICAgY29uc3QgVUNoYXIgKmluOwoKICAgICAgICBjaGFyIGJ1ZmZlclsyMF07CiAgICAgICAgY2hhciAqb3V0OwoKICAgICAgICBpbiA9IGE7CiAgICAgICAgb3V0ID0gYnVmZmVyOwogICAgICAgIGVyciA9IFVfWkVST19FUlJPUjsKICAgICAgICB1Y252X2Zyb21Vbmljb2RlKGNudiwKICAgICAgICAgICAgJm91dCwgYnVmZmVyICsgc2l6ZW9mKGJ1ZmZlciksCiAgICAgICAgICAgICZpbiwgYSArIDEsCiAgICAgICAgICAgIE5VTEwsIFRSVUUsICZlcnIpOwogICAgICAgIHVjbnZfcmVzZXRGcm9tVW5pY29kZShjbnYpOwoKICAgICAgICBpZiAoTlVMTCAhPSB1Y252X2RldGVjdFVuaWNvZGVTaWduYXR1cmUoYnVmZmVyLCAoaW50MzJfdCkob3V0IC0gYnVmZmVyKSwgTlVMTCwgJmVycikgJiYKICAgICAgICAgICAgVV9TVUNDRVNTKGVycikKICAgICAgICApIHsKICAgICAgICAgICAgcmVzdWx0ID0gQ05WX0FERFNfRkVGRjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQoKY2xhc3MgQ29udmVydEZpbGUgewpwdWJsaWM6CiAgICBDb252ZXJ0RmlsZSgpIDoKICAgICAgICBidWYoTlVMTCksIG91dGJ1ZihOVUxMKSwgZnJvbW9mZnNldHMoTlVMTCksCiAgICAgICAgYnVmc3ooMCksIHNpZ25hdHVyZSgwKSB7fQoKICAgIHZvaWQKICAgIHNldEJ1ZmZlclNpemUoc2l6ZV90IGJ1ZmZlclNpemUpIHsKICAgICAgICBidWZzeiA9IGJ1ZmZlclNpemU7CgogICAgICAgIGJ1ZiA9IG5ldyBjaGFyWzIgKiBidWZzel07CiAgICAgICAgb3V0YnVmID0gYnVmICsgYnVmc3o7CgogICAgICAgIC8vICsxIGZvciBhbiBhZGRlZCBVK0ZFRkYgaW4gdGhlIGludGVybWVkaWF0ZSBVbmljb2RlIGJ1ZmZlcgogICAgICAgIGZyb21vZmZzZXRzID0gbmV3IGludDMyX3RbYnVmc3ogKyAxXTsKICAgIH0KCiAgICB+Q29udmVydEZpbGUoKSB7CiAgICAgICAgZGVsZXRlIFtdIGJ1ZjsKICAgICAgICBkZWxldGUgW10gZnJvbW9mZnNldHM7CiAgICB9CgogICAgVUJvb2wgY29udmVydEZpbGUoY29uc3QgY2hhciAqcG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpmcm9tY3BhZ2UsCiAgICAgICAgICAgICAgICAgICAgICBVQ29udmVydGVyVG9VQ2FsbGJhY2sgdG91Y2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICp0b3VjdHh0LAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqdG9jcGFnZSwKICAgICAgICAgICAgICAgICAgICAgIFVDb252ZXJ0ZXJGcm9tVUNhbGxiYWNrIGZyb211Y2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpmcm9tdWN0eHQsCiAgICAgICAgICAgICAgICAgICAgICBVQm9vbCBmYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRyYW5zbGl0LAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqaW5maWxlc3RyLAogICAgICAgICAgICAgICAgICAgICAgRklMRSAqIG91dGZpbGUsIGludCB2ZXJib3NlKTsKcHJpdmF0ZToKICAgIGZyaWVuZCBpbnQgbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpOwoKICAgIGNoYXIgKmJ1ZiwgKm91dGJ1ZjsKICAgIGludDMyX3QgKmZyb21vZmZzZXRzOwoKICAgIHNpemVfdCBidWZzejsKICAgIGludDhfdCBzaWduYXR1cmU7IC8vIGFkZCAoMSkgb3IgcmVtb3ZlICgtMSkgYSBVK0ZFRkYgVW5pY29kZSBzaWduYXR1cmUgY2hhcmFjdGVyCn07CgovLyBDb252ZXJ0IGEgZmlsZSBmcm9tIG9uZSBlbmNvZGluZyB0byBhbm90aGVyClVCb29sCkNvbnZlcnRGaWxlOjpjb252ZXJ0RmlsZShjb25zdCBjaGFyICpwbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmZyb21jcGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgIFVDb252ZXJ0ZXJUb1VDYWxsYmFjayB0b3VjYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnRvdWN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2NwYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgVUNvbnZlcnRlckZyb21VQ2FsbGJhY2sgZnJvbXVjYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmZyb211Y3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sIGZhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqdHJhbnNsaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICppbmZpbGVzdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFICogb3V0ZmlsZSwgaW50IHZlcmJvc2UpCnsKICAgIEZJTEUgKmluZmlsZTsKICAgIFVCb29sIHJldCA9IFRSVUU7CiAgICBVQ29udmVydGVyICpjb252ZnJvbSA9IDA7CiAgICBVQ29udmVydGVyICpjb252dG8gPSAwOwogICAgVUVycm9yQ29kZSBlcnIgPSBVX1pFUk9fRVJST1I7CiAgICBVQm9vbCBmbHVzaDsKICAgIGNvbnN0IGNoYXIgKmNidWZwLCAqcHJldmJ1ZnA7CiAgICBjaGFyICpidWZwOwoKICAgIHVpbnQzMl90IGluZm9mZnNldCA9IDAsIG91dGZvZmZzZXQgPSAwOyAgIC8qIFdoZXJlIHdlIGFyZSBpbiB0aGUgZmlsZSwgZm9yIGVycm9yIHJlcG9ydGluZy4gKi8KCiAgICBjb25zdCBVQ2hhciAqdW5pYnVmLCAqdW5pYnVmYnA7CiAgICBVQ2hhciAqdW5pYnVmcDsKCiAgICBzaXplX3QgcmQsIHdyOwoKI2lmICFVQ09ORklHX05PX1RSQU5TTElURVJBVElPTgogICAgVHJhbnNsaXRlcmF0b3IgKnQgPSAwOyAgICAgIC8vIFRyYW5zbGl0ZXJhdG9yIGFjdGluZyBvbiBVbmljb2RlIGRhdGEuCiAgICBVbmljb2RlU3RyaW5nIGNodW5rOyAgICAgICAgLy8gT25lIGNodW5rIG9mIHRoZSB0ZXh0IGJlaW5nIGNvbGxlY3RlZCBmb3IgdHJhbnNmb3JtYXRpb24uCiNlbmRpZgogICAgVW5pY29kZVN0cmluZyB1OyAgICAgICAgICAgIC8vIFN0cmluZyB0byBkbyB0aGUgdHJhbnNsaXRlcmF0aW9uLgogICAgaW50MzJfdCB1bGVuOwoKICAgIC8vIHVzZSBjb252ZXJzaW9uIG9mZnNldHMgZm9yIGVycm9yIG1lc3NhZ2VzCiAgICAvLyB1bmxlc3MgYSB0cmFuc2xpdGVyYXRvciBpcyB1c2VkIC0KICAgIC8vIGEgdGV4dCB0cmFuc2Zvcm1hdGlvbiB3aWxsIHJlb3JkZXIgY2hhcmFjdGVycyBpbiB1bnByZWRpY3RhYmxlIHdheXMKICAgIFVCb29sIHVzZU9mZnNldHMgPSBUUlVFOwoKICAgIC8vIE9wZW4gdGhlIGNvcnJlY3QgaW5wdXQgZmlsZSBvciBjb25uZWN0IHRvIHN0ZGluIGZvciByZWFkaW5nIGlucHV0CgogICAgaWYgKGluZmlsZXN0ciAhPSAwICYmIHN0cmNtcChpbmZpbGVzdHIsICItIikpIHsKICAgICAgICBpbmZpbGUgPSBmb3BlbihpbmZpbGVzdHIsICJyYiIpOwogICAgICAgIGlmIChpbmZpbGUgPT0gMCkgewogICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cjEoaW5maWxlc3RyLCAiIik7CiAgICAgICAgICAgIHN0cjEuYXBwZW5kKChVQ2hhcjMyKSAwKTsKICAgICAgICAgICAgVW5pY29kZVN0cmluZyBzdHIyKHN0cmVycm9yKGVycm5vKSwgIiIpOwogICAgICAgICAgICBzdHIyLmFwcGVuZCgoVUNoYXIzMikgMCk7CiAgICAgICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudE9wZW5JbnB1dEYiLCBzdHIxLmdldEJ1ZmZlcigpLCBzdHIyLmdldEJ1ZmZlcigpKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaW5maWxlc3RyID0gIi0iOwogICAgICAgIGluZmlsZSA9IHN0ZGluOwojaWYgZGVmaW5lZChXSU4zMikgfHwgZGVmaW5lZChVX0NZR1dJTikKICAgICAgICBpZiAoc2V0bW9kZShmaWxlbm8oc3RkaW4pLCBPX0JJTkFSWSkgPT0gLTEpIHsKICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50U2V0SW5CaW5Nb2RlIik7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiNlbmRpZgogICAgfQoKICAgIGlmICh2ZXJib3NlKSB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICIlczpcbiIsIGluZmlsZXN0cik7CiAgICB9CgojaWYgIVVDT05GSUdfTk9fVFJBTlNMSVRFUkFUSU9OCiAgICAvLyBDcmVhdGUgdHJhbnNsaXRlcmF0b3IgYXMgbmVlZGVkLgoKICAgIGlmICh0cmFuc2xpdCAhPSBOVUxMICYmICp0cmFuc2xpdCkgewogICAgICAgIFVQYXJzZUVycm9yIHBhcnNlOwogICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKHRyYW5zbGl0KSwgcGVzdHI7CgogICAgICAgIC8qIENyZWF0ZSBmcm9tIHJ1bGVzIG9yIGJ5IElEIGFzIG5lZWRlZC4gKi8KCiAgICAgICAgcGFyc2UubGluZSA9IC0xOwoKICAgICAgICBpZiAodXBydl9zdHJjaHIodHJhbnNsaXQsICc6JykgfHwgdXBydl9zdHJjaHIodHJhbnNsaXQsICc+JykgfHwgdXBydl9zdHJjaHIodHJhbnNsaXQsICc8JykgfHwgdXBydl9zdHJjaHIodHJhbnNsaXQsICc+JykpIHsKICAgICAgICAgICAgdCA9IFRyYW5zbGl0ZXJhdG9yOjpjcmVhdGVGcm9tUnVsZXMoIlVjb252Iiwgc3RyLCBVVFJBTlNfRk9SV0FSRCwgcGFyc2UsIGVycik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdCA9IFRyYW5zbGl0ZXJhdG9yOjpjcmVhdGVJbnN0YW5jZSh0cmFuc2xpdCwgVVRSQU5TX0ZPUldBUkQsIGVycik7CiAgICAgICAgfQoKICAgICAgICBpZiAoVV9GQUlMVVJFKGVycikpIHsKICAgICAgICAgICAgc3RyLmFwcGVuZCgoVUNoYXIzMikgMCk7CiAgICAgICAgICAgIGluaXRNc2cocG5hbWUpOwoKICAgICAgICAgICAgaWYgKHBhcnNlLmxpbmUgPj0gMCkgewogICAgICAgICAgICAgICAgVUNoYXIgbGluZWJ1ZlsyMF0sIG9mZnNldGJ1ZlsyMF07CiAgICAgICAgICAgICAgICB1cHJ2X2l0b3UobGluZWJ1ZiwgMjAsIHBhcnNlLmxpbmUsIDEwLCAwKTsKICAgICAgICAgICAgICAgIHVwcnZfaXRvdShvZmZzZXRidWYsIDIwLCBwYXJzZS5vZmZzZXQsIDEwLCAwKTsKICAgICAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50Q3JlYXRlVHJhbnNsaXRQYXJzZUVyciIsIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCksCiAgICAgICAgICAgICAgICAgICAgdV93bXNnX2Vycm9yTmFtZShlcnIpLCBsaW5lYnVmLCBvZmZzZXRidWYpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRDcmVhdGVUcmFuc2xpdCIsIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCksCiAgICAgICAgICAgICAgICAgICAgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHQpIHsKICAgICAgICAgICAgICAgIGRlbGV0ZSB0OwogICAgICAgICAgICAgICAgdCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ290byBlcnJvcl9leGl0OwogICAgICAgIH0KCiAgICAgICAgdXNlT2Zmc2V0cyA9IEZBTFNFOwogICAgfQojZW5kaWYKCiAgICAvLyBDcmVhdGUgY29kZXBhZ2UgY29udmVydGVyLiBJZiB0aGUgY29kZXBhZ2Ugb3IgaXRzIGFsaWFzZXMgd2VyZW4ndAogICAgLy8gYXZhaWxhYmxlLCBpdCByZXR1cm5zIE5VTEwgYW5kIGEgZmFpbHVyZSBjb2RlLiBXZSBhbHNvIHNldCB0aGUKICAgIC8vIGNhbGxiYWNrcywgYW5kIHJldHVybiBlcnJvcnMgaW4gdGhlIHNhbWUgd2F5LgoKICAgIGNvbnZmcm9tID0gdWNudl9vcGVuKGZyb21jcGFnZSwgJmVycik7CiAgICBpZiAoVV9GQUlMVVJFKGVycikpIHsKICAgICAgICBVbmljb2RlU3RyaW5nIHN0cihmcm9tY3BhZ2UsICIiKTsKICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudE9wZW5Gcm9tQ29kZXNldCIsIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCksCiAgICAgICAgICAgIHVfd21zZ19lcnJvck5hbWUoZXJyKSk7CiAgICAgICAgZ290byBlcnJvcl9leGl0OwogICAgfQogICAgdWNudl9zZXRUb1VDYWxsQmFjayhjb252ZnJvbSwgdG91Y2FsbGJhY2ssIHRvdWN0eHQsIDAsIDAsICZlcnIpOwogICAgaWYgKFVfRkFJTFVSRShlcnIpKSB7CiAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRTZXRDYWxsYmFjayIsIHVfd21zZ19lcnJvck5hbWUoZXJyKSk7CiAgICAgICAgZ290byBlcnJvcl9leGl0OwogICAgfQoKICAgIGNvbnZ0byA9IHVjbnZfb3Blbih0b2NwYWdlLCAmZXJyKTsKICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKHRvY3BhZ2UsICIiKTsKICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudE9wZW5Ub0NvZGVzZXQiLCBzdHIuZ2V0VGVybWluYXRlZEJ1ZmZlcigpLAogICAgICAgICAgICB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwogICAgICAgIGdvdG8gZXJyb3JfZXhpdDsKICAgIH0KICAgIHVjbnZfc2V0RnJvbVVDYWxsQmFjayhjb252dG8sIGZyb211Y2FsbGJhY2ssIGZyb211Y3R4dCwgMCwgMCwgJmVycik7CiAgICBpZiAoVV9GQUlMVVJFKGVycikpIHsKICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudFNldENhbGxiYWNrIiwgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgICBnb3RvIGVycm9yX2V4aXQ7CiAgICB9CiAgICB1Y252X3NldEZhbGxiYWNrKGNvbnZ0bywgZmFsbGJhY2spOwoKICAgIFVCb29sIHdpbGxleGl0LCBmcm9tU2F3RW5kT2ZCeXRlcywgdG9TYXdFbmRPZlVuaWNvZGU7CiAgICBpbnQ4X3Qgc2lnOwoKICAgIC8vIE9LLCB3ZSBjYW4gY29udmVydCBub3cuCiAgICBzaWcgPSBzaWduYXR1cmU7CiAgICByZCA9IDA7CgogICAgZG8gewogICAgICAgIHdpbGxleGl0ID0gRkFMU0U7CgogICAgICAgIC8vIGlucHV0IGZpbGUgb2Zmc2V0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5leHQgYnVmZmVyCiAgICAgICAgaW5mb2Zmc2V0ICs9IHJkOwoKICAgICAgICByZCA9IGZyZWFkKGJ1ZiwgMSwgYnVmc3osIGluZmlsZSk7CiAgICAgICAgaWYgKGZlcnJvcihpbmZpbGUpICE9IDApIHsKICAgICAgICAgICAgVW5pY29kZVN0cmluZyBzdHIoc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50UmVhZCIsIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCkpOwogICAgICAgICAgICBnb3RvIGVycm9yX2V4aXQ7CiAgICAgICAgfQoKICAgICAgICAvLyBDb252ZXJ0IHRoZSByZWFkIGJ1ZmZlciBpbnRvIHRoZSBuZXcgZW5jb2RpbmcgdmlhIFVuaWNvZGUuCiAgICAgICAgLy8gQWZ0ZXIgdGhlIGNhbGwgJ3VuaWJ1ZnAnIHdpbGwgYmUgcGxhY2VkIGJlaGluZCB0aGUgbGFzdAogICAgICAgIC8vIGNoYXJhY3RlciB0aGF0IHdhcyBjb252ZXJ0ZWQgaW4gdGhlICd1bmlidWYnLgogICAgICAgIC8vIEFsc28gdGhlICdjYnVmcCcgaXMgcG9zaXRpb25lZCBiZWhpbmQgdGhlIGxhc3QgY29udmVydGVkCiAgICAgICAgLy8gY2hhcmFjdGVyLgogICAgICAgIC8vIEF0IHRoZSBsYXN0IGNvbnZlcnNpb24gaW4gdGhlIGZpbGUsIGZsdXNoIHNob3VsZCBiZSBzZXQgdG8KICAgICAgICAvLyB0cnVlIHNvIHRoYXQgd2UgZ2V0IGFsbCBjaGFyYWN0ZXJzIGNvbnZlcnRlZC4KICAgICAgICAvLwogICAgICAgIC8vIFRoZSBjb252ZXJ0ZXIgbXVzdCBiZSBmbHVzaGVkIGF0IHRoZSBlbmQgb2YgY29udmVyc2lvbiBzbwogICAgICAgIC8vIHRoYXQgY2hhcmFjdGVycyBvbiBob2xkIGFsc28gd2lsbCBiZSB3cml0dGVuLgoKICAgICAgICBjYnVmcCA9IGJ1ZjsKICAgICAgICBmbHVzaCA9IChVQm9vbCkocmQgIT0gYnVmc3opOwoKICAgICAgICAvLyBjb252ZXJ0IHVudGlsIHRoZSBpbnB1dCBpcyBjb25zdW1lZAogICAgICAgIGRvIHsKICAgICAgICAgICAgLy8gcmVtZW1iZXIgdGhlIHN0YXJ0IG9mIHRoZSBjdXJyZW50IGJ5dGUtdG8tVW5pY29kZSBjb252ZXJzaW9uCiAgICAgICAgICAgIHByZXZidWZwID0gY2J1ZnA7CgogICAgICAgICAgICB1bmlidWYgPSB1bmlidWZwID0gdS5nZXRCdWZmZXIoKGludDMyX3QpYnVmc3opOwoKICAgICAgICAgICAgLy8gVXNlIGJ1ZnN6IGluc3RlYWQgb2YgdS5nZXRDYXBhY2l0eSgpIGZvciB0aGUgdGFyZ2V0TGltaXQKICAgICAgICAgICAgLy8gc28gdGhhdCB3ZSBkb24ndCBvdmVyZmxvdyBmcm9tb2Zmc2V0c1tdLgogICAgICAgICAgICB1Y252X3RvVW5pY29kZShjb252ZnJvbSwgJnVuaWJ1ZnAsIHVuaWJ1ZiArIGJ1ZnN6LCAmY2J1ZnAsCiAgICAgICAgICAgICAgICBidWYgKyByZCwgdXNlT2Zmc2V0cyA/IGZyb21vZmZzZXRzIDogTlVMTCwgZmx1c2gsICZlcnIpOwoKICAgICAgICAgICAgdWxlbiA9IChpbnQzMl90KSh1bmlidWZwIC0gdW5pYnVmKTsKICAgICAgICAgICAgdS5yZWxlYXNlQnVmZmVyKHVsZW4pOwoKICAgICAgICAgICAgLy8gZnJvbVNhd0VuZE9mQnl0ZXMgaW5kaWNhdGVzIHRoYXQgdWNudl90b1VuaWNvZGUoKSBpcyBkb25lCiAgICAgICAgICAgIC8vIGNvbnZlcnRpbmcgYWxsIG9mIHRoZSBpbnB1dCBieXRlcy4KICAgICAgICAgICAgLy8gSXQgd29ya3MgbGlrZSB0aGlzIGJlY2F1c2UgdWNudl90b1VuaWNvZGUoKSByZXR1cm5zIG9ubHkgdW5kZXIgdGhlCiAgICAgICAgICAgIC8vIGZvbGxvd2luZyBjb25kaXRpb25zOgogICAgICAgICAgICAvLyAtIGFuIGVycm9yIG9jY3VycmVkIGR1cmluZyBjb252ZXJzaW9uIChhbiBlcnJvciBjb2RlIGlzIHNldCkKICAgICAgICAgICAgLy8gLSB0aGUgdGFyZ2V0IGJ1ZmZlciBpcyBmaWxsZWQgKHRoZSBlcnJvciBjb2RlIGluZGljYXRlcyBhbiBvdmVyZmxvdykKICAgICAgICAgICAgLy8gLSB0aGUgc291cmNlIGlzIGNvbnN1bWVkCiAgICAgICAgICAgIC8vIFRoYXQgaXMsIGlmIHRoZSBlcnJvciBjb2RlIGRvZXMgbm90IGluZGljYXRlIGEgZmFpbHVyZSwKICAgICAgICAgICAgLy8gbm90IGV2ZW4gYW4gb3ZlcmZsb3csIHRoZW4gdGhlIHNvdXJjZSBtdXN0IGJlIGNvbnN1bWVkIGVudGlyZWx5LgogICAgICAgICAgICBmcm9tU2F3RW5kT2ZCeXRlcyA9IChVQm9vbClVX1NVQ0NFU1MoZXJyKTsKCiAgICAgICAgICAgIGlmIChlcnIgPT0gVV9CVUZGRVJfT1ZFUkZMT1dfRVJST1IpIHsKICAgICAgICAgICAgICAgIGVyciA9IFVfWkVST19FUlJPUjsKICAgICAgICAgICAgfSBlbHNlIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgICAgICAgICAgY2hhciBwb3NbMzJdLCBlcnJvckJ5dGVzWzMyXTsKICAgICAgICAgICAgICAgIGludDhfdCBpLCBsZW5ndGgsIGVycm9yTGVuZ3RoOwoKICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgbG9jYWxFcnJvciA9IFVfWkVST19FUlJPUjsKICAgICAgICAgICAgICAgIGVycm9yTGVuZ3RoID0gKGludDhfdClzaXplb2YoZXJyb3JCeXRlcyk7CiAgICAgICAgICAgICAgICB1Y252X2dldEludmFsaWRDaGFycyhjb252ZnJvbSwgZXJyb3JCeXRlcywgJmVycm9yTGVuZ3RoLCAmbG9jYWxFcnJvcik7CiAgICAgICAgICAgICAgICBpZiAoVV9GQUlMVVJFKGxvY2FsRXJyb3IpIHx8IGVycm9yTGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICBlcnJvckxlbmd0aCA9IDE7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gcHJpbnQgdGhlIGlucHV0IGZpbGUgb2Zmc2V0IG9mIHRoZSBzdGFydCBvZiB0aGUgZXJyb3IgYnl0ZXM6CiAgICAgICAgICAgICAgICAvLyBpbnB1dCBmaWxlIG9mZnNldCBvZiB0aGUgY3VycmVudCBieXRlIGJ1ZmZlciArCiAgICAgICAgICAgICAgICAvLyBsZW5ndGggb2YgdGhlIGp1c3QgY29uc3VtZWQgYnl0ZXMgLQogICAgICAgICAgICAgICAgLy8gbGVuZ3RoIG9mIHRoZSBlcnJvciBieXRlcwogICAgICAgICAgICAgICAgbGVuZ3RoID0KICAgICAgICAgICAgICAgICAgICAoaW50OF90KXNwcmludGYocG9zLCAiJWQiLAogICAgICAgICAgICAgICAgICAgICAgICAoaW50KShpbmZvZmZzZXQgKyAoY2J1ZnAgLSBidWYpIC0gZXJyb3JMZW5ndGgpKTsKCiAgICAgICAgICAgICAgICAvLyBvdXRwdXQgdGhlIGJ5dGVzIHRoYXQgY2F1c2VkIHRoZSBlcnJvcgogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBzdHI7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXJyb3JMZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKChVQ2hhcil1U1ApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKG5pYmJsZVRvSGV4KCh1aW50OF90KWVycm9yQnl0ZXNbaV0gPj4gNCkpOwogICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQobmliYmxlVG9IZXgoKHVpbnQ4X3QpZXJyb3JCeXRlc1tpXSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgInByb2JsZW1DdnRUb1UiLAogICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nKHBvcywgbGVuZ3RoLCAiIikuZ2V0VGVybWluYXRlZEJ1ZmZlcigpLAogICAgICAgICAgICAgICAgICAgICAgICBzdHIuZ2V0VGVybWluYXRlZEJ1ZmZlcigpLAogICAgICAgICAgICAgICAgICAgICAgICB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwoKICAgICAgICAgICAgICAgIHdpbGxleGl0ID0gVFJVRTsKICAgICAgICAgICAgICAgIGVyciA9IFVfWkVST19FUlJPUjsgLyogcmVzZXQgdGhlIGVycm9yIGZvciB0aGUgcmVzdCBvZiB0aGUgY29udmVyc2lvbi4gKi8KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUmVwbGFjZWQgYSBjaGVjayBmb3Igd2hldGhlciB0aGUgaW5wdXQgd2FzIGNvbnN1bWVkIGJ5CiAgICAgICAgICAgIC8vIGxvb3BpbmcgdW50aWwgaXQgaXM7IG1lc3NhZ2Uga2V5ICJwcmVtRW5kSW5wdXQiIG5vdyBvYnNvbGV0ZS4KCiAgICAgICAgICAgIGlmICh1bGVuID09IDApIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyByZW1vdmUgYSBVK0ZFRkYgVW5pY29kZSBzaWduYXR1cmUgY2hhcmFjdGVyIGlmIHJlcXVlc3RlZAogICAgICAgICAgICBpZiAoc2lnIDwgMCkgewogICAgICAgICAgICAgICAgaWYgKHUuY2hhckF0KDApID09IHVTaWcpIHsKICAgICAgICAgICAgICAgICAgICB1LnJlbW92ZSgwLCAxKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHJlbW92ZWQgVUNoYXIgYW5kIG9mZnNldAogICAgICAgICAgICAgICAgICAgIC0tdWxlbjsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHVzZU9mZnNldHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGFuIG9mZnNldCBmcm9tIGZyb21vZmZzZXRzW10gYXMgd2VsbAogICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBrZWVwIHRoZSBhcnJheSBwYXJhbGxlbCB3aXRoIHRoZSBVQ2hhcnMKICAgICAgICAgICAgICAgICAgICAgICAgbWVtbW92ZShmcm9tb2Zmc2V0cywgZnJvbW9mZnNldHMgKyAxLCB1bGVuICogNCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNpZyA9IDA7CiAgICAgICAgICAgIH0KCiNpZiAhVUNPTkZJR19OT19UUkFOU0xJVEVSQVRJT04KICAgICAgICAgICAgLy8gVHJhbnNsaXRlcmF0ZS90cmFuc2Zvcm0gaWYgbmVlZGVkLgoKICAgICAgICAgICAgLy8gRm9yIHRyYW5zZm9ybWF0aW9uLCB3ZSB1c2UgY2h1bmtpbmcgY29kZSAtCiAgICAgICAgICAgIC8vIGNvbGxlY3QgVW5pY29kZSBpbnB1dCB1bnRpbCwgZm9yIGV4YW1wbGUsIGFuIGVuZC1vZi1saW5lLAogICAgICAgICAgICAvLyB0aGVuIHRyYW5zZm9ybSBhbmQgb3V0cHV0LWNvbnZlcnQgdGhhdCBhbmQgY29udGludWUgY29sbGVjdGluZy4KICAgICAgICAgICAgLy8gVGhpcyBtYWtlcyB0aGUgdHJhbnNmb3JtYXRpb24gcmVzdWx0IGluZGVwZW5kZW50IG9mIHRoZSBidWZmZXIgc2l6ZQogICAgICAgICAgICAvLyB3aGlsZSBhdm9pZGluZyB0aGUgc2xvd2VyIGtleWJvYXJkIG1vZGUuCiAgICAgICAgICAgIC8vIFRoZSBlbmQtb2YtY2h1bmsgY2hhcmFjdGVycyBhcmUgY29tcGxldGVseSBpbmNsdWRlZCBpbiB0aGUKICAgICAgICAgICAgLy8gdHJhbnNmb3JtZWQgc3RyaW5nIGluIGNhc2UgdGhleSBhcmUgdG8gYmUgdHJhbnNmb3JtZWQgdGhlbXNlbHZlcy4KICAgICAgICAgICAgaWYgKHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBvdXQ7CiAgICAgICAgICAgICAgICBpbnQzMl90IGNodW5rTGltaXQ7CgogICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgIGNodW5rTGltaXQgPSBnZXRDaHVua0xpbWl0KGNodW5rLCB1KTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2h1bmtMaW1pdCA8IDAgJiYgZmx1c2ggJiYgZnJvbVNhd0VuZE9mQnl0ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlIGFsbCBvZiB0aGUgcmVzdCBhdCB0aGUgZW5kIG9mIHRoZSB0ZXh0CiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rTGltaXQgPSB1Lmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoY2h1bmtMaW1pdCA+PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbXBsZXRlIHRoZSBjaHVuayBhbmQgdHJhbnNmb3JtIGl0CiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLmFwcGVuZCh1LCAwLCBjaHVua0xpbWl0KTsKICAgICAgICAgICAgICAgICAgICAgICAgdS5yZW1vdmUoMCwgY2h1bmtMaW1pdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHQtPnRyYW5zbGl0ZXJhdGUoY2h1bmspOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXBwZW5kIHRoZSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQgdG8gdGhlIHJlc3VsdCBhbmQgZW1wdHkgdGhlIGNodW5rCiAgICAgICAgICAgICAgICAgICAgICAgIG91dC5hcHBlbmQoY2h1bmspOwogICAgICAgICAgICAgICAgICAgICAgICBjaHVuay5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBjb250aW51ZSBjb2xsZWN0aW5nIHRoZSBjaHVuawogICAgICAgICAgICAgICAgICAgICAgICBjaHVuay5hcHBlbmQodSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gd2hpbGUgKCF1LmlzRW1wdHkoKSk7CgogICAgICAgICAgICAgICAgdSA9IG91dDsKICAgICAgICAgICAgICAgIHVsZW4gPSB1Lmxlbmd0aCgpOwogICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgLy8gYWRkIGEgVStGRUZGIFVuaWNvZGUgc2lnbmF0dXJlIGNoYXJhY3RlciBpZiByZXF1ZXN0ZWQKICAgICAgICAgICAgLy8gYW5kIHBvc3NpYmxlL25lY2Vzc2FyeQogICAgICAgICAgICBpZiAoc2lnID4gMCkgewogICAgICAgICAgICAgICAgaWYgKHUuY2hhckF0KDApICE9IHVTaWcgJiYgY252U2lnVHlwZShjb252dG8pID09IENOVl9XSVRIX0ZFRkYpIHsKICAgICAgICAgICAgICAgICAgICB1Lmluc2VydCgwLCAoVUNoYXIpdVNpZyk7CgogICAgICAgICAgICAgICAgICAgIGlmICh1c2VPZmZzZXRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc2VydCBhIHBzZXVkby1vZmZzZXQgaW50byBmcm9tb2Zmc2V0c1tdIGFzIHdlbGwKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8ga2VlcCB0aGUgYXJyYXkgcGFyYWxsZWwgd2l0aCB0aGUgVUNoYXJzCiAgICAgICAgICAgICAgICAgICAgICAgIG1lbW1vdmUoZnJvbW9mZnNldHMgKyAxLCBmcm9tb2Zmc2V0cywgdWxlbiAqIDQpOwogICAgICAgICAgICAgICAgICAgICAgICBmcm9tb2Zmc2V0c1swXSA9IC0xOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIGFkZGl0aW9uYWwgVUNoYXIgYW5kIG9mZnNldAogICAgICAgICAgICAgICAgICAgICsrdWxlbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNpZyA9IDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIFVuaWNvZGUgYnVmZmVyIGludG8gdGhlIGRlc3RpbmF0aW9uIGNvZGVwYWdlCiAgICAgICAgICAgIC8vIEFnYWluICdidWZwJyB3aWxsIGJlIHBsYWNlZCBiZWhpbmQgdGhlIGxhc3QgY29udmVydGVkIGNoYXJhY3RlcgogICAgICAgICAgICAvLyBBbmQgJ3VuaWJ1ZnAnIHdpbGwgYmUgcGxhY2VkIGJlaGluZCB0aGUgbGFzdCBjb252ZXJ0ZWQgdW5pY29kZSBjaGFyYWN0ZXIKICAgICAgICAgICAgLy8gQXQgdGhlIGxhc3QgY29udmVyc2lvbiBmbHVzaCBzaG91bGQgYmUgc2V0IHRvIHRydWUgdG8gZW5zdXJlIHRoYXQKICAgICAgICAgICAgLy8gYWxsIGNoYXJhY3RlcnMgbGVmdCBnZXQgY29udmVydGVkCgogICAgICAgICAgICB1bmlidWYgPSB1bmlidWZicCA9IHUuZ2V0QnVmZmVyKCk7CgogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICBidWZwID0gb3V0YnVmOwoKICAgICAgICAgICAgICAgIC8vIFVzZSBmcm9tU2F3RW5kT2ZCeXRlcyBpbiBhZGRpdGlvbiB0byB0aGUgZmx1c2ggZmxhZyAtCiAgICAgICAgICAgICAgICAvLyBpdCBpbmRpY2F0ZXMgd2hldGhlciB0aGUgaW50ZXJtZWRpYXRlIFVuaWNvZGUgc3RyaW5nCiAgICAgICAgICAgICAgICAvLyBjb250YWlucyB0aGUgdmVyeSBsYXN0IFVDaGFycyBmb3IgdGhlIHZlcnkgbGFzdCBpbnB1dCBieXRlcy4KICAgICAgICAgICAgICAgIHVjbnZfZnJvbVVuaWNvZGUoY29udnRvLCAmYnVmcCwgb3V0YnVmICsgYnVmc3osCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ1bmlidWZicCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pYnVmICsgdWxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgKFVCb29sKShmbHVzaCAmJiBmcm9tU2F3RW5kT2ZCeXRlcyksICZlcnIpOwoKICAgICAgICAgICAgICAgIC8vIHRvU2F3RW5kT2ZVbmljb2RlIGluZGljYXRlcyB0aGF0IHVjbnZfZnJvbVVuaWNvZGUoKSBpcyBkb25lCiAgICAgICAgICAgICAgICAvLyBjb252ZXJ0aW5nIGFsbCBvZiB0aGUgaW50ZXJtZWRpYXRlIFVDaGFycy4KICAgICAgICAgICAgICAgIC8vIFNlZSBjb21tZW50IGZvciBmcm9tU2F3RW5kT2ZCeXRlcy4KICAgICAgICAgICAgICAgIHRvU2F3RW5kT2ZVbmljb2RlID0gKFVCb29sKVVfU1VDQ0VTUyhlcnIpOwoKICAgICAgICAgICAgICAgIGlmIChlcnIgPT0gVV9CVUZGRVJfT1ZFUkZMT1dfRVJST1IpIHsKICAgICAgICAgICAgICAgICAgICBlcnIgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFVfRkFJTFVSRShlcnIpKSB7CiAgICAgICAgICAgICAgICAgICAgVUNoYXIgZXJyb3JVQ2hhcnNbNF07CiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJydGFnOwogICAgICAgICAgICAgICAgICAgIGNoYXIgcG9zWzMyXTsKICAgICAgICAgICAgICAgICAgICBVQ2hhcjMyIGM7CiAgICAgICAgICAgICAgICAgICAgaW50OF90IGksIGxlbmd0aCwgZXJyb3JMZW5ndGg7CgogICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgbG9jYWxFcnJvciA9IFVfWkVST19FUlJPUjsKICAgICAgICAgICAgICAgICAgICBlcnJvckxlbmd0aCA9IChpbnQ4X3QpTEVOR1RIT0YoZXJyb3JVQ2hhcnMpOwogICAgICAgICAgICAgICAgICAgIHVjbnZfZ2V0SW52YWxpZFVDaGFycyhjb252dG8sIGVycm9yVUNoYXJzLCAmZXJyb3JMZW5ndGgsICZsb2NhbEVycm9yKTsKICAgICAgICAgICAgICAgICAgICBpZiAoVV9GQUlMVVJFKGxvY2FsRXJyb3IpIHx8IGVycm9yTGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVlZCBhdCBsZWFzdCAxIHNvIHRoYXQgd2UgZG9uJ3QgYWNjZXNzIGJleW9uZCB0aGUgbGVuZ3RoIG9mIGZyb21vZmZzZXRzW10KICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JMZW5ndGggPSAxOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBmZXJyb2Zmc2V0OwoKICAgICAgICAgICAgICAgICAgICBpZiAodXNlT2Zmc2V0cykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBVbmljb2RlIGJ1ZmZlciBvZmZzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZSBlcnJvciBVQ2hhcnMKICAgICAgICAgICAgICAgICAgICAgICAgZmVycm9mZnNldCA9IChpbnQzMl90KSgodW5pYnVmYnAgLSB1bmlidWYpIC0gZXJyb3JMZW5ndGgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmVycm9mZnNldCA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFwcHJveGltYXRpb24gLSB0aGUgY2hhcmFjdGVyIHN0YXJ0ZWQgaW4gdGhlIHByZXZpb3VzIFVuaWNvZGUgYnVmZmVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZXJyb2Zmc2V0ID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBjb3JyZXNwb25kaW5nIGJ5dGUgb2Zmc2V0IG91dCBvZiBmcm9tb2Zmc2V0c1tdCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdvIGJhY2sgaWYgdGhlIG9mZnNldCBpcyBub3Qga25vd24gZm9yIHNvbWUgb2YgdGhlIFVDaGFycwogICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGZyb21vZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21vZmZzZXQgPSBmcm9tb2Zmc2V0c1tmZXJyb2Zmc2V0XTsKICAgICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoZnJvbW9mZnNldCA8IDAgJiYgLS1mZXJyb2Zmc2V0ID49IDApOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG90YWwgaW5wdXQgZmlsZSBvZmZzZXQgPQogICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnB1dCBmaWxlIG9mZnNldCBvZiB0aGUgY3VycmVudCBieXRlIGJ1ZmZlciArCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ5dGUgYnVmZmVyIG9mZnNldCBvZiB3aGVyZSB0aGUgY3VycmVudCBVbmljb2RlIGJ1ZmZlciBpcyBjb252ZXJ0ZWQgZnJvbSArCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZyb21vZmZzZXRzW1VuaWNvZGUgb2Zmc2V0XQogICAgICAgICAgICAgICAgICAgICAgICBmZXJyb2Zmc2V0ID0gaW5mb2Zmc2V0ICsgKHByZXZidWZwIC0gYnVmKSArIGZyb21vZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGVycnRhZyA9ICJwcm9ibGVtQ3Z0RnJvbVUiOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIERvIG5vdCB1c2UgZnJvbW9mZnNldHMgaWYgKHQgIT0gTlVMTCkgYmVjYXVzZSB0aGUgVW5pY29kZSB0ZXh0IG1heQogICAgICAgICAgICAgICAgICAgICAgICAvLyBiZSBkaWZmZXJlbnQgZnJvbSB3aGF0IHRoZSBvZmZzZXRzIHJlZmVyIHRvLgoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0cHV0IGZpbGUgb2Zmc2V0CiAgICAgICAgICAgICAgICAgICAgICAgIGZlcnJvZmZzZXQgPSAoaW50MzJfdCkob3V0Zm9mZnNldCArIChidWZwIC0gb3V0YnVmKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGVycnRhZyA9ICJwcm9ibGVtQ3Z0RnJvbVVPdXQiOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gKGludDhfdClzcHJpbnRmKHBvcywgIiV1IiwgZmVycm9mZnNldCk7CgogICAgICAgICAgICAgICAgICAgIC8vIG91dHB1dCB0aGUgY29kZSBwb2ludHMgdGhhdCBjYXVzZWQgdGhlIGVycm9yCiAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBzdHI7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGVycm9yTGVuZ3RoOykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoKFVDaGFyKXVTUCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgVTE2X05FWFQoZXJyb3JVQ2hhcnMsIGksIGVycm9yTGVuZ3RoLCBjKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgPj0gMHgxMDAwMDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQobmliYmxlVG9IZXgoKHVpbnQ4X3QpKGMgPj4gMjApKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgPj0gMHgxMDAwMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChuaWJibGVUb0hleCgodWludDhfdCkoYyA+PiAxNikpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKG5pYmJsZVRvSGV4KCh1aW50OF90KShjID4+IDEyKSkpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKG5pYmJsZVRvSGV4KCh1aW50OF90KShjID4+IDgpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQobmliYmxlVG9IZXgoKHVpbnQ4X3QpKGMgPj4gNCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChuaWJibGVUb0hleCgodWludDhfdCljKSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCBlcnJ0YWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nKHBvcywgbGVuZ3RoLCAiIikuZ2V0VGVybWluYXRlZEJ1ZmZlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiZXJyb3JVbmljb2RlIiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSk7CgogICAgICAgICAgICAgICAgICAgIHdpbGxleGl0ID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICBlcnIgPSBVX1pFUk9fRVJST1I7IC8qIHJlc2V0IHRoZSBlcnJvciBmb3IgdGhlIHJlc3Qgb2YgdGhlIGNvbnZlcnNpb24uICovCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gUmVwbGFjZWQgYSBjaGVjayBmb3Igd2hldGhlciB0aGUgaW50ZXJtZWRpYXRlIFVuaWNvZGUgY2hhcmFjdGVycyB3ZXJlIGFsbCBjb25zdW1lZCBieQogICAgICAgICAgICAgICAgLy8gbG9vcGluZyB1bnRpbCB0aGV5IGFyZTsgbWVzc2FnZSBrZXkgInByZW1FbmQiIG5vdyBvYnNvbGV0ZS4KCiAgICAgICAgICAgICAgICAvLyBGaW5hbGx5LCB3cml0ZSB0aGUgY29udmVydGVkIGJ1ZmZlciB0byB0aGUgb3V0cHV0IGZpbGUKICAgICAgICAgICAgICAgIHNpemVfdCBvdXRsZW4gPSAoc2l6ZV90KSAoYnVmcCAtIG91dGJ1Zik7CiAgICAgICAgICAgICAgICBvdXRmb2Zmc2V0ICs9IChpbnQzMl90KSh3ciA9IGZ3cml0ZShvdXRidWYsIDEsIG91dGxlbiwgb3V0ZmlsZSkpOwogICAgICAgICAgICAgICAgaWYgKHdyICE9IG91dGxlbikgewogICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRXcml0ZSIsIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCkpOwogICAgICAgICAgICAgICAgICAgIHdpbGxleGl0ID0gVFJVRTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAod2lsbGV4aXQpIHsKICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yX2V4aXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gd2hpbGUgKCF0b1Nhd0VuZE9mVW5pY29kZSk7CiAgICAgICAgfSB3aGlsZSAoIWZyb21TYXdFbmRPZkJ5dGVzKTsKICAgIH0gd2hpbGUgKCFmbHVzaCk7ICAgICAgICAgICAvLyBTdG9wIHdoZW4gd2UgaGF2ZSBmbHVzaGVkIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnRlcnMgKHRoaXMgbWVhbnMgdGhhdCBpdCdzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGVuZCBvZiBvdXRwdXQpCgogICAgZ290byBub3JtYWxfZXhpdDsKCmVycm9yX2V4aXQ6CiAgICByZXQgPSBGQUxTRTsKCm5vcm1hbF9leGl0OgogICAgLy8gQ2xlYW51cC4KCiAgICB1Y252X2Nsb3NlKGNvbnZmcm9tKTsKICAgIHVjbnZfY2xvc2UoY29udnRvKTsKCiNpZiAhVUNPTkZJR19OT19UUkFOU0xJVEVSQVRJT04KICAgIGRlbGV0ZSB0OwojZW5kaWYKCiAgICBpZiAoaW5maWxlICE9IHN0ZGluKSB7CiAgICAgICAgZmNsb3NlKGluZmlsZSk7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgdXNhZ2UoY29uc3QgY2hhciAqcG5hbWUsIGludCBlY29kZSkgewogICAgY29uc3QgVUNoYXIgKm1zZzsKICAgIGludDMyX3QgbXNnTGVuOwogICAgVUVycm9yQ29kZSBlcnIgPSBVX1pFUk9fRVJST1I7CiAgICBGSUxFICpmcCA9IGVjb2RlID8gc3RkZXJyIDogc3Rkb3V0OwogICAgaW50IHJlczsKCiAgICBpbml0TXNnKHBuYW1lKTsKICAgIG1zZyA9CiAgICAgICAgdXJlc19nZXRTdHJpbmdCeUtleShnQnVuZGxlLCBlY29kZSA/ICJsY1VzYWdlV29yZCIgOiAidWNVc2FnZVdvcmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1zZ0xlbiwgJmVycik7CiAgICBVbmljb2RlU3RyaW5nIHVwbmFtZShwbmFtZSwgKGludDMyX3QpKHVwcnZfc3RybGVuKHBuYW1lKSArIDEpKTsKICAgIFVuaWNvZGVTdHJpbmcgbW5hbWUobXNnLCBtc2dMZW4gKyAxKTsKCiAgICByZXMgPSB1X3dtc2coZnAsICJ1c2FnZSIsIG1uYW1lLmdldEJ1ZmZlcigpLCB1cG5hbWUuZ2V0QnVmZmVyKCkpOwogICAgaWYgKCFlY29kZSkgewogICAgICAgIGlmICghcmVzKSB7CiAgICAgICAgICAgIGZwdXRjKCdcbicsIGZwKTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1X3dtc2coZnAsICJoZWxwIikpIHsKICAgICAgICAgICAgLyogTm93IGR1bXAgY2FsbGJhY2tzIGFuZCBmaW5pc2guICovCgogICAgICAgICAgICBpbnQgaSwgY291bnQgPQogICAgICAgICAgICAgICAgc2l6ZW9mKHRyYW5zY29kZV9jYWxsYmFja3MpIC8gc2l6ZW9mKCp0cmFuc2NvZGVfY2FsbGJhY2tzKTsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKICAgICAgICAgICAgICAgIGZwcmludGYoZnAsICIgJXMiLCB0cmFuc2NvZGVfY2FsbGJhY2tzW2ldLm5hbWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZwdXRjKCdcbicsIGZwKTsKICAgICAgICB9CiAgICB9CgogICAgZXhpdChlY29kZSk7Cn0KCmV4dGVybiBpbnQKbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKICAgIEZJTEUgKm91dGZpbGU7CiAgICBpbnQgcmV0ID0gMDsKCiAgICBzaXplX3QgYnVmc3ogPSBERUZBVUxUX0JVRlNaOwoKICAgIGNvbnN0IGNoYXIgKmZyb21jcGFnZSA9IDA7CiAgICBjb25zdCBjaGFyICp0b2NwYWdlID0gMDsKICAgIGNvbnN0IGNoYXIgKnRyYW5zbGl0ID0gMDsKICAgIGNvbnN0IGNoYXIgKm91dGZpbGVzdHIgPSAwOwogICAgVUJvb2wgZmFsbGJhY2sgPSBGQUxTRTsKCiAgICBVQ29udmVydGVyRnJvbVVDYWxsYmFjayBmcm9tdWNhbGxiYWNrID0gVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfU1RPUDsKICAgIGNvbnN0IHZvaWQgKmZyb211Y3R4dCA9IDA7CiAgICBVQ29udmVydGVyVG9VQ2FsbGJhY2sgdG91Y2FsbGJhY2sgPSBVQ05WX1RPX1VfQ0FMTEJBQ0tfU1RPUDsKICAgIGNvbnN0IHZvaWQgKnRvdWN0eHQgPSAwOwoKICAgIGNoYXIgKippdGVyLCAqKnJlbWFpbkFyZ3YsICoqcmVtYWluQXJndkxpbWl0OwogICAgY2hhciAqKmVuZCA9IGFyZ3YgKyBhcmdjOwoKICAgIGNvbnN0IGNoYXIgKnBuYW1lOwoKICAgIFVCb29sIHByaW50Q29udnMgPSBGQUxTRSwgcHJpbnRDYW5vbiA9IEZBTFNFLCBwcmludFRyYW5zbGl0cyA9IEZBTFNFOwogICAgY29uc3QgY2hhciAqcHJpbnROYW1lID0gMDsKCiAgICBVQm9vbCB2ZXJib3NlID0gRkFMU0U7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICBDb252ZXJ0RmlsZSBjZjsKCiAgICAvKiBJbml0aWFsaXplIElDVSAqLwogICAgdV9pbml0KCZzdGF0dXMpOwogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICIlczogY2FuIG5vdCBpbml0aWFsaXplIElDVS4gIHN0YXR1cyA9ICVzXG4iLAogICAgICAgICAgICBhcmd2WzBdLCB1X2Vycm9yTmFtZShzdGF0dXMpKTsKICAgICAgICBleGl0KDEpOwogICAgfQoKICAgIC8vIEdldCBhbmQgcHJldHRpZnkgcG5hbWUuCiAgICBwbmFtZSA9IHVwcnZfc3RycmNocigqYXJndiwgVV9GSUxFX1NFUF9DSEFSKTsKI2lmZGVmIFdJTjMyCiAgICBpZiAoIXBuYW1lKSB7CiAgICAgICAgcG5hbWUgPSB1cHJ2X3N0cnJjaHIoKmFyZ3YsICcvJyk7CiAgICB9CiNlbmRpZgogICAgaWYgKCFwbmFtZSkgewogICAgICAgIHBuYW1lID0gKmFyZ3Y7CiAgICB9IGVsc2UgewogICAgICAgICsrcG5hbWU7CiAgICB9CgogICAgLy8gRmlyc3QsIGdldCB0aGUgYXJndW1lbnRzIGZyb20gY29tbWFuZC1saW5lCiAgICAvLyB0byBrbm93IHRoZSBjb2RlcGFnZXMgdG8gY29udmVydCBiZXR3ZWVuCgogICAgcmVtYWluQXJndiA9IHJlbWFpbkFyZ3ZMaW1pdCA9IGFyZ3YgKyAxOwogICAgZm9yIChpdGVyID0gYXJndiArIDE7IGl0ZXIgIT0gZW5kOyBpdGVyKyspIHsKICAgICAgICAvLyBDaGVjayBmb3IgZnJvbSBjaGFyc2V0CiAgICAgICAgaWYgKHN0cmNtcCgiLWYiLCAqaXRlcikgPT0gMCB8fCAhc3RyY21wKCItLWZyb20tY29kZSIsICppdGVyKSkgewogICAgICAgICAgICBpdGVyKys7CiAgICAgICAgICAgIGlmIChpdGVyICE9IGVuZCkKICAgICAgICAgICAgICAgIGZyb21jcGFnZSA9ICppdGVyOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgfSBlbHNlIGlmIChzdHJjbXAoIi10IiwgKml0ZXIpID09IDAgfHwgIXN0cmNtcCgiLS10by1jb2RlIiwgKml0ZXIpKSB7CiAgICAgICAgICAgIGl0ZXIrKzsKICAgICAgICAgICAgaWYgKGl0ZXIgIT0gZW5kKQogICAgICAgICAgICAgICAgdG9jcGFnZSA9ICppdGVyOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgfSBlbHNlIGlmIChzdHJjbXAoIi14IiwgKml0ZXIpID09IDApIHsKICAgICAgICAgICAgaXRlcisrOwogICAgICAgICAgICBpZiAoaXRlciAhPSBlbmQpCiAgICAgICAgICAgICAgICB0cmFuc2xpdCA9ICppdGVyOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgfSBlbHNlIGlmICghc3RyY21wKCItLWZhbGxiYWNrIiwgKml0ZXIpKSB7CiAgICAgICAgICAgIGZhbGxiYWNrID0gVFJVRTsKICAgICAgICB9IGVsc2UgaWYgKCFzdHJjbXAoIi0tbm8tZmFsbGJhY2siLCAqaXRlcikpIHsKICAgICAgICAgICAgZmFsbGJhY2sgPSBGQUxTRTsKICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcCgiLWIiLCAqaXRlcikgPT0gMCB8fCAhc3RyY21wKCItLWJsb2NrLXNpemUiLCAqaXRlcikpIHsKICAgICAgICAgICAgaXRlcisrOwogICAgICAgICAgICBpZiAoaXRlciAhPSBlbmQpIHsKICAgICAgICAgICAgICAgIGJ1ZnN6ID0gYXRvaSgqaXRlcik7CiAgICAgICAgICAgICAgICBpZiAoKGludCkgYnVmc3ogPD0gMCkgewogICAgICAgICAgICAgICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKCppdGVyKTsKICAgICAgICAgICAgICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiYmFkQmxvY2tTaXplIiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcCgiLWwiLCAqaXRlcikgPT0gMCB8fCAhc3RyY21wKCItLWxpc3QiLCAqaXRlcikpIHsKICAgICAgICAgICAgaWYgKHByaW50VHJhbnNsaXRzKSB7CiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnRDb252cyA9IFRSVUU7CiAgICAgICAgfSBlbHNlIGlmIChzdHJjbXAoIi0tZGVmYXVsdC1jb2RlIiwgKml0ZXIpID09IDApIHsKICAgICAgICAgICAgaWYgKHByaW50VHJhbnNsaXRzKSB7CiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnROYW1lID0gdWNudl9nZXREZWZhdWx0TmFtZSgpOwogICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKCItLWxpc3QtY29kZSIsICppdGVyKSA9PSAwKSB7CiAgICAgICAgICAgIGlmIChwcmludFRyYW5zbGl0cykgewogICAgICAgICAgICAgICAgdXNhZ2UocG5hbWUsIDEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpdGVyKys7CiAgICAgICAgICAgIGlmIChpdGVyICE9IGVuZCkgewogICAgICAgICAgICAgICAgVUVycm9yQ29kZSBlID0gVV9aRVJPX0VSUk9SOwogICAgICAgICAgICAgICAgcHJpbnROYW1lID0gdWNudl9nZXRBbGlhcygqaXRlciwgMCwgJmUpOwogICAgICAgICAgICAgICAgaWYgKFVfRkFJTFVSRShlKSB8fCAhcHJpbnROYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBzdHIoKml0ZXIpOwogICAgICAgICAgICAgICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJub1N1Y2hDb2Rlc2V0Iiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgdXNhZ2UocG5hbWUsIDEpOwogICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKCItLWNhbm9uIiwgKml0ZXIpID09IDApIHsKICAgICAgICAgICAgcHJpbnRDYW5vbiA9IFRSVUU7CiAgICAgICAgfSBlbHNlIGlmIChzdHJjbXAoIi1MIiwgKml0ZXIpID09IDAKICAgICAgICAgICAgfHwgIXN0cmNtcCgiLS1saXN0LXRyYW5zbGl0ZXJhdG9ycyIsICppdGVyKSkgewogICAgICAgICAgICBpZiAocHJpbnRDb252cykgewogICAgICAgICAgICAgICAgdXNhZ2UocG5hbWUsIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByaW50VHJhbnNsaXRzID0gVFJVRTsKICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcCgiLWgiLCAqaXRlcikgPT0gMCB8fCAhc3RyY21wKCItPyIsICppdGVyKQogICAgICAgICAgICB8fCAhc3RyY21wKCItLWhlbHAiLCAqaXRlcikpIHsKICAgICAgICAgICAgdXNhZ2UocG5hbWUsIDApOwogICAgICAgIH0gZWxzZSBpZiAoIXN0cmNtcCgiLWMiLCAqaXRlcikpIHsKICAgICAgICAgICAgZnJvbXVjYWxsYmFjayA9IFVDTlZfRlJPTV9VX0NBTExCQUNLX1NLSVA7CiAgICAgICAgfSBlbHNlIGlmICghc3RyY21wKCItLXRvLWNhbGxiYWNrIiwgKml0ZXIpKSB7CiAgICAgICAgICAgIGl0ZXIrKzsKICAgICAgICAgICAgaWYgKGl0ZXIgIT0gZW5kKSB7CiAgICAgICAgICAgICAgICBjb25zdCBzdHJ1Y3QgY2FsbGJhY2tfZW50ICpjYmUgPSBmaW5kQ2FsbGJhY2soKml0ZXIpOwogICAgICAgICAgICAgICAgaWYgKGNiZSkgewogICAgICAgICAgICAgICAgICAgIGZyb211Y2FsbGJhY2sgPSBjYmUtPmZyb211OwogICAgICAgICAgICAgICAgICAgIGZyb211Y3R4dCA9IGNiZS0+ZnJvbXVjdHh0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cigqaXRlcik7CiAgICAgICAgICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgInVua25vd25DYWxsYmFjayIsIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiA0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdXNhZ2UocG5hbWUsIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICghc3RyY21wKCItLWZyb20tY2FsbGJhY2siLCAqaXRlcikpIHsKICAgICAgICAgICAgaXRlcisrOwogICAgICAgICAgICBpZiAoaXRlciAhPSBlbmQpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBjYWxsYmFja19lbnQgKmNiZSA9IGZpbmRDYWxsYmFjaygqaXRlcik7CiAgICAgICAgICAgICAgICBpZiAoY2JlKSB7CiAgICAgICAgICAgICAgICAgICAgdG91Y2FsbGJhY2sgPSBjYmUtPnRvdTsKICAgICAgICAgICAgICAgICAgICB0b3VjdHh0ID0gY2JlLT50b3VjdHh0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cigqaXRlcik7CiAgICAgICAgICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgInVua25vd25DYWxsYmFjayIsIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiA0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdXNhZ2UocG5hbWUsIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICghc3RyY21wKCItaSIsICppdGVyKSkgewogICAgICAgICAgICB0b3VjYWxsYmFjayA9IFVDTlZfVE9fVV9DQUxMQkFDS19TS0lQOwogICAgICAgIH0gZWxzZSBpZiAoIXN0cmNtcCgiLS1jYWxsYmFjayIsICppdGVyKSkgewogICAgICAgICAgICBpdGVyKys7CiAgICAgICAgICAgIGlmIChpdGVyICE9IGVuZCkgewogICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IGNhbGxiYWNrX2VudCAqY2JlID0gZmluZENhbGxiYWNrKCppdGVyKTsKICAgICAgICAgICAgICAgIGlmIChjYmUpIHsKICAgICAgICAgICAgICAgICAgICBmcm9tdWNhbGxiYWNrID0gY2JlLT5mcm9tdTsKICAgICAgICAgICAgICAgICAgICBmcm9tdWN0eHQgPSBjYmUtPmZyb211Y3R4dDsKICAgICAgICAgICAgICAgICAgICB0b3VjYWxsYmFjayA9IGNiZS0+dG91OwogICAgICAgICAgICAgICAgICAgIHRvdWN0eHQgPSBjYmUtPnRvdWN0eHQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKCppdGVyKTsKICAgICAgICAgICAgICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAidW5rbm93bkNhbGxiYWNrIiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKCFzdHJjbXAoIi1zIiwgKml0ZXIpIHx8ICFzdHJjbXAoIi0tc2lsZW50IiwgKml0ZXIpKSB7CiAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRTsKICAgICAgICB9IGVsc2UgaWYgKCFzdHJjbXAoIi12IiwgKml0ZXIpIHx8ICFzdHJjbXAoIi0tdmVyYm9zZSIsICppdGVyKSkgewogICAgICAgICAgICB2ZXJib3NlID0gVFJVRTsKICAgICAgICB9IGVsc2UgaWYgKCFzdHJjbXAoIi1WIiwgKml0ZXIpIHx8ICFzdHJjbXAoIi0tdmVyc2lvbiIsICppdGVyKSkgewogICAgICAgICAgICBwcmludGYoIiVzIHYyLjEgIElDVSAiIFVfSUNVX1ZFUlNJT04gIlxuIiwgcG5hbWUpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9IGVsc2UgaWYgKCFzdHJjbXAoIi1vIiwgKml0ZXIpIHx8ICFzdHJjbXAoIi0tb3V0cHV0IiwgKml0ZXIpKSB7CiAgICAgICAgICAgICsraXRlcjsKICAgICAgICAgICAgaWYgKGl0ZXIgIT0gZW5kICYmICFvdXRmaWxlc3RyKSB7CiAgICAgICAgICAgICAgICBvdXRmaWxlc3RyID0gKml0ZXI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKDAgPT0gc3RyY21wKCItLWFkZC1zaWduYXR1cmUiLCAqaXRlcikpIHsKICAgICAgICAgICAgY2Yuc2lnbmF0dXJlID0gMTsKICAgICAgICB9IGVsc2UgaWYgKDAgPT0gc3RyY21wKCItLXJlbW92ZS1zaWduYXR1cmUiLCAqaXRlcikpIHsKICAgICAgICAgICAgY2Yuc2lnbmF0dXJlID0gLTE7CiAgICAgICAgfSBlbHNlIGlmICgqKml0ZXIgPT0gJy0nICYmICgqaXRlcilbMV0pIHsKICAgICAgICAgICAgdXNhZ2UocG5hbWUsIDEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIG1vdmUgYSBub24tb3B0aW9uIHVwIGluIGFyZ3ZbXQogICAgICAgICAgICAqcmVtYWluQXJndkxpbWl0KysgPSAqaXRlcjsKICAgICAgICB9CiAgICB9CgogICAgaWYgKHByaW50Q29udnMgfHwgcHJpbnROYW1lKSB7CiAgICAgICAgcmV0dXJuIHByaW50Q29udmVydGVycyhwbmFtZSwgcHJpbnROYW1lLCBwcmludENhbm9uKSA/IDIgOiAwOwogICAgfSBlbHNlIGlmIChwcmludFRyYW5zbGl0cykgewogICAgICAgIHJldHVybiBwcmludFRyYW5zbGl0ZXJhdG9ycyhwcmludENhbm9uKSA/IDMgOiAwOwogICAgfQoKICAgIGlmICghZnJvbWNwYWdlIHx8ICF1cHJ2X3N0cmNtcChmcm9tY3BhZ2UsICItIikpIHsKICAgICAgICBmcm9tY3BhZ2UgPSB1Y252X2dldERlZmF1bHROYW1lKCk7CiAgICB9CiAgICBpZiAoIXRvY3BhZ2UgfHwgIXVwcnZfc3RyY21wKHRvY3BhZ2UsICItIikpIHsKICAgICAgICB0b2NwYWdlID0gdWNudl9nZXREZWZhdWx0TmFtZSgpOwogICAgfQoKICAgIC8vIE9wZW4gdGhlIGNvcnJlY3Qgb3V0cHV0IGZpbGUgb3IgY29ubmVjdCB0byBzdGRvdXQgZm9yIHJlYWRpbmcgaW5wdXQKICAgIGlmIChvdXRmaWxlc3RyICE9IDAgJiYgc3RyY21wKG91dGZpbGVzdHIsICItIikpIHsKICAgICAgICBvdXRmaWxlID0gZm9wZW4ob3V0ZmlsZXN0ciwgIndiIik7CiAgICAgICAgaWYgKG91dGZpbGUgPT0gMCkgewogICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cjEob3V0ZmlsZXN0ciwgIiIpOwogICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cjIoc3RyZXJyb3IoZXJybm8pLCAiIik7CiAgICAgICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudENyZWF0ZU91dHB1dEYiLAogICAgICAgICAgICAgICAgc3RyMS5nZXRCdWZmZXIoKSwgc3RyMi5nZXRCdWZmZXIoKSk7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgb3V0ZmlsZXN0ciA9ICItIjsKICAgICAgICBvdXRmaWxlID0gc3Rkb3V0OwojaWYgZGVmaW5lZChXSU4zMikgfHwgZGVmaW5lZChVX0NZR1dJTikKICAgICAgICBpZiAoc2V0bW9kZShmaWxlbm8ob3V0ZmlsZSksIE9fQklOQVJZKSA9PSAtMSkgewogICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudFNldE91dEJpbk1vZGUiKTsKICAgICAgICAgICAgZXhpdCgtMSk7CiAgICAgICAgfQojZW5kaWYKICAgIH0KCiAgICAvKiBMb29wIGFnYWluIG9uIHRoZSBhcmd1bWVudHMgdG8gZmluZCBhbGwgdGhlIGlucHV0IGZpbGVzLCBhbmQKICAgIGNvbnZlcnQgdGhlbS4gKi8KCiAgICBjZi5zZXRCdWZmZXJTaXplKGJ1ZnN6KTsKCiAgICBpZihyZW1haW5Bcmd2IDwgcmVtYWluQXJndkxpbWl0KSB7CiAgICAgICAgZm9yIChpdGVyID0gcmVtYWluQXJndjsgaXRlciAhPSByZW1haW5Bcmd2TGltaXQ7IGl0ZXIrKykgewogICAgICAgICAgICBpZiAoIWNmLmNvbnZlcnRGaWxlKAogICAgICAgICAgICAgICAgICAgIHBuYW1lLCBmcm9tY3BhZ2UsIHRvdWNhbGxiYWNrLCB0b3VjdHh0LCB0b2NwYWdlLAogICAgICAgICAgICAgICAgICAgIGZyb211Y2FsbGJhY2ssIGZyb211Y3R4dCwgZmFsbGJhY2ssIHRyYW5zbGl0LCAqaXRlciwKICAgICAgICAgICAgICAgICAgICBvdXRmaWxlLCB2ZXJib3NlKQogICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgIGdvdG8gZXJyb3JfZXhpdDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFjZi5jb252ZXJ0RmlsZSgKICAgICAgICAgICAgICAgIHBuYW1lLCBmcm9tY3BhZ2UsIHRvdWNhbGxiYWNrLCB0b3VjdHh0LCB0b2NwYWdlLAogICAgICAgICAgICAgICAgZnJvbXVjYWxsYmFjaywgZnJvbXVjdHh0LCBmYWxsYmFjaywgdHJhbnNsaXQsIDAsCiAgICAgICAgICAgICAgICBvdXRmaWxlLCB2ZXJib3NlKQogICAgICAgICkgewogICAgICAgICAgICBnb3RvIGVycm9yX2V4aXQ7CiAgICAgICAgfQogICAgfQoKICAgIGdvdG8gbm9ybWFsX2V4aXQ7CmVycm9yX2V4aXQ6CiAgICByZXQgPSAxOwpub3JtYWxfZXhpdDoKCiAgICBpZiAob3V0ZmlsZSAhPSBzdGRvdXQpIHsKICAgICAgICBmY2xvc2Uob3V0ZmlsZSk7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKCi8qCiAqIEhleSwgRW1hY3MsIHBsZWFzZSBzZXQgdGhlIGZvbGxvd2luZzoKICoKICogTG9jYWwgVmFyaWFibGVzOgogKiBpbmRlbnQtdGFicy1tb2RlOiBuaWwKICogRW5kOgogKgogKi8K