LyoKICoJaGFuZGxpbmcgb2YgU0hFTEwzMi5ETEwgT0xFLU9iamVjdHMKICoKICoJQ29weXJpZ2h0IDE5OTcJTWFyY3VzIE1laXNzbmVyCiAqCUNvcHlyaWdodCAxOTk4CUp1ZXJnZW4gU2NobWllZCAgPGp1ZXJnZW4uc2NobWllZEBtZXRyb25ldC5kZT4KICoKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ3aW5lL29ial9iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL29ial9zaGVsbGxpbmsuaCIKI2luY2x1ZGUgIndpbmUvb2JqX3NoZWxsZm9sZGVyLmgiCiNpbmNsdWRlICJ3aW5lL29ial9zaGVsbGJyb3dzZXIuaCIKI2luY2x1ZGUgIndpbmUvb2JqX2NvbnRleHRtZW51LmgiCiNpbmNsdWRlICJ3aW5lL29ial9zaGVsbGV4dGluaXQuaCIKI2luY2x1ZGUgIndpbmUvb2JqX2V4dHJhY3RpY29uLmgiCgojaW5jbHVkZSAic2hsZ3VpZC5oIgojaW5jbHVkZSAid2ludmVyc2lvbi5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKI2luY2x1ZGUgInNoZWxsMzJfbWFpbi5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHNoZWxsKQoKRFdPUkQgV0lOQVBJIFNIQ0xTSURGcm9tU3RyaW5nQSAoTFBTVFIgY2xzaWQsIENMU0lEICppZCk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENvQ3JlYXRlSW5zdGFuY2UgW1NIRUxMMzIuMTAyXQogKiAKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCkxSRVNVTFQgV0lOQVBJIFNIQ29DcmVhdGVJbnN0YW5jZSgKCUxQU1RSIGFjbHNpZCwKCVJFRkNMU0lEIGNsc2lkLAoJSVVua25vd24gKiB1bmtub3dub3V0ZXIsCglSRUZJSUQgcmVmaWlkLAoJTFBWT0lEICpwcHYpCnsKCWNoYXIJeGNsc2lkWzQ4XSwgeGlpZFs0OF07CglEV09SRAlocmVzOwoJSUlECWlpZDsKCUNMU0lEICogbXljbHNpZCA9IChDTFNJRCopY2xzaWQ7CgkKCVdJTkVfU3RyaW5nRnJvbUNMU0lEKHJlZmlpZCx4aWlkKTsKCglpZiAoIWNsc2lkKQoJewoJICBpZiAoIWFjbHNpZCkgcmV0dXJuIFJFR0RCX0VfQ0xBU1NOT1RSRUc7CgkgIFNIQ0xTSURGcm9tU3RyaW5nQShhY2xzaWQsICZpaWQpOwoJICBteWNsc2lkID0gJmlpZDsKCX0KCglXSU5FX1N0cmluZ0Zyb21DTFNJRChteWNsc2lkLHhjbHNpZCk7CglXSU5FX1N0cmluZ0Zyb21DTFNJRChyZWZpaWQseGlpZCk7CgkgIAoJVFJBQ0UoIiglcCxcblx0Q0xTSUQ6XHQlcywgdW5rOiVwXG5cdElJRDpcdCVzLCVwKVxuIiwKCQlhY2xzaWQseGNsc2lkLHVua25vd25vdXRlcix4aWlkLHBwdik7CgoJaHJlcyA9IENvQ3JlYXRlSW5zdGFuY2UobXljbHNpZCwgdW5rbm93bm91dGVyLCBDTFNDVFhfSU5QUk9DX1NFUlZFUiwgcmVmaWlkLCBwcHYpOwoKCWlmKGhyZXMhPVNfT0spCgl7CgkgIEVSUigiZmFpbGVkICgweCUwOGx4KSB0byBjcmVhdGUgXG5cdENMU0lEOlx0JXNcblx0SUlEOlx0JXNcbiIsIGhyZXMsIHhjbHNpZCwgeGlpZCk7CgkgIEVSUigieW91IG1pZ2h0IG5lZWQgdG8gaW1wb3J0IHRoZSB3aW5lZGVmYXVsdC5yZWdcbiIpOwoJfQoKCXJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTDMyX0RsbEdldENsYXNzT2JqZWN0ICAgW1NIRUxMMzIuMTI4XQogKi8KSFJFU1VMVCBXSU5BUEkgU0hFTEwzMl9EbGxHZXRDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsTFBWT0lEICpwcHYpCnsJSFJFU1VMVAlocmVzID0gRV9PVVRPRk1FTU9SWTsKCUxQQ0xBU1NGQUNUT1JZIGxwY2xmOwoKCWNoYXIgeGNsc2lkWzUwXSx4aWlkWzUwXTsKCVdJTkVfU3RyaW5nRnJvbUNMU0lEKChMUENMU0lEKXJjbHNpZCx4Y2xzaWQpOwoJV0lORV9TdHJpbmdGcm9tQ0xTSUQoKExQQ0xTSUQpaWlkLHhpaWQpOwoJVFJBQ0UoIlxuXHRDTFNJRDpcdCVzLFxuXHRJSUQ6XHQlc1xuIix4Y2xzaWQseGlpZCk7CgkKCSpwcHYgPSBOVUxMOwoKCWlmKElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9QYXBlckJpbikpCgl7CgkgIEVSUigicGFwZXIgYmluIG5vdCBpbXBsZW1lbnRlZFxuIik7CgkgIHJldHVybiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFOwoJfQoJaWYoSXNFcXVhbENMU0lEKHJjbHNpZCwgJkNMU0lEX1NoZWxsRGVza3RvcCl8fCAKCSAgIElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9TaGVsbExpbmspKQoJewoJICBscGNsZiA9IElDbGFzc0ZhY3RvcnlfQ29uc3RydWN0b3IoIHJjbHNpZCApOwoKCSAgaWYobHBjbGYpIAoJICB7CgkgICAgaHJlcyA9IElDbGFzc0ZhY3RvcnlfUXVlcnlJbnRlcmZhY2UobHBjbGYsaWlkLCBwcHYpOwoJICAgIElDbGFzc0ZhY3RvcnlfUmVsZWFzZShscGNsZik7CgkgIH0KCX0KCWVsc2UKCXsKCSAgV0FSTigiLS0gQ0xTSUQgbm90IGZvdW5kXG4iKTsKCSAgaHJlcyA9IENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7Cgl9CglUUkFDRSgiLS0gcG9pbnRlciB0byBjbGFzcyBmYWN0b3J5OiAlcFxuIiwqcHB2KTsKCXJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENMU0lERnJvbVN0cmluZwkJCQlbU0hFTEwzMi4xNDddCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpEV09SRCBXSU5BUEkgU0hDTFNJREZyb21TdHJpbmdBIChMUFNUUiBjbHNpZCwgQ0xTSUQgKmlkKQp7CglUUkFDRSgiKCVwKCVzKSAlcClcbiIsIGNsc2lkLCBjbHNpZCwgaWQpOwoJcmV0dXJuIENMU0lERnJvbVN0cmluZzE2KGNsc2lkLCBpZCk7IAp9CkRXT1JEIFdJTkFQSSBTSENMU0lERnJvbVN0cmluZ1cgKExQV1NUUiBjbHNpZCwgQ0xTSUQgKmlkKQp7CglUUkFDRSgiKCVwKCVzKSAlcClcbiIsIGNsc2lkLCBkZWJ1Z3N0cl93KGNsc2lkKSwgaWQpOwoJcmV0dXJuIENMU0lERnJvbVN0cmluZyhjbHNpZCwgaWQpOyAKfQpEV09SRCBXSU5BUEkgU0hDTFNJREZyb21TdHJpbmdBVyAoTFBWT0lEIGNsc2lkLCBDTFNJRCAqaWQpCnsKCWlmIChWRVJTSU9OX09zSXNVbmljb2RlKCkpCgkgIHJldHVybiBTSENMU0lERnJvbVN0cmluZ1cgKGNsc2lkLCBpZCk7CglyZXR1cm4gU0hDTFNJREZyb21TdHJpbmdBIChjbHNpZCwgaWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCSBTSEdldE1hbGxvYwkJCVtTSEVMTDMyLjIyMF0KICogcmV0dXJucyB0aGUgaW50ZXJmYWNlIHRvIHNoZWxsIG1hbGxvYy4KICoKICogW1NESyBoZWFkZXIgd2luOTUvc2hsb2JqLmg6CiAqIGVxdWl2YWxlbnQgdG86ICAjZGVmaW5lIFNIR2V0TWFsbG9jKHBwbWVtKSAgIENvR2V0TWFsbG9jKE1FTUNUWF9UQVNLLCBwcG1lbSkKICogXQogKiBXaGF0IHdlIGFyZSBjdXJyZW50bHkgZG9pbmcgaXMgbm90IHZlcnkgd3JvbmcsIHNpbmNlIHdlIGFsd2F5cyB1c2UgdGhlIHNhbWUKICogaGVhcCAoUHJvY2Vzc0hlYXApLgogKi8KRFdPUkQgV0lOQVBJIFNIR2V0TWFsbG9jKExQTUFMTE9DICpscG1hbCkgCnsKCVRSQUNFKCIoJXApXG4iLCBscG1hbCk7CglyZXR1cm4gQ29HZXRNYWxsb2MoMCxscG1hbCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0RGVza3RvcEZvbGRlcgkJCVtTSEVMTDMyLjIxNl0KICovCkxQU0hFTExGT0xERVIgcGRlc2t0b3Bmb2xkZXI9TlVMTDsKCkRXT1JEIFdJTkFQSSBTSEdldERlc2t0b3BGb2xkZXIoSVNoZWxsRm9sZGVyICoqcHNmKQp7CglIUkVTVUxUCWhyZXMgPSBTX09LOwoJTFBDTEFTU0ZBQ1RPUlkgbHBjbGY7CglUUkFDRV8oc2hlbGwpKCIlcC0+KCVwKVxuIixwc2YsKnBzZik7CgoJKnBzZj1OVUxMOwoKCWlmICghcGRlc2t0b3Bmb2xkZXIpIAoJewoJICBscGNsZiA9IElDbGFzc0ZhY3RvcnlfQ29uc3RydWN0b3IoJkNMU0lEX1NoZWxsRGVza3RvcCk7CgkgIGlmKGxwY2xmKSAKCSAgewoJICAgIGhyZXMgPSBJQ2xhc3NGYWN0b3J5X0NyZWF0ZUluc3RhbmNlKGxwY2xmLE5VTEwsKFJFRklJRCkmSUlEX0lTaGVsbEZvbGRlciwgKHZvaWQqKSZwZGVza3RvcGZvbGRlcik7CgkgICAgSUNsYXNzRmFjdG9yeV9SZWxlYXNlKGxwY2xmKTsKCSAgfSAgCgl9CgkKCWlmIChwZGVza3RvcGZvbGRlcikgCgl7CgkgIC8qIGV2ZW4gaWYgd2UgY3JlYXRlIHRoZSBmb2xkZXIsIGFkZCBhIHJlZiBzbyB0aGUgYXBwbGljYXRpb24gY2FutHQgZGVzdHJveSB0aGUgZm9sZGVyKi8KCSAgSVNoZWxsRm9sZGVyX0FkZFJlZihwZGVza3RvcGZvbGRlcik7CgkgICpwc2YgPSBwZGVza3RvcGZvbGRlcjsKCX0KCglUUkFDRV8oc2hlbGwpKCItLSAlcC0+KCVwKVxuIixwc2YsICpwc2YpOwoJcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICBJQ2xhc3NGYWN0b3J5IEltcGxlbWVudGF0aW9uCiovCgp0eXBlZGVmIHN0cnVjdAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElDbGFzc0ZhY3RvcnkpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKICAgIENMU0lECQkJKnJjbHNpZDsKfSBJQ2xhc3NGYWN0b3J5SW1wbDsKCnN0YXRpYyBJQ09NX1ZUQUJMRShJQ2xhc3NGYWN0b3J5KSBjbGZ2dDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUNsYXNzRmFjdG9yeV9Db25zdHJ1Y3RvcgogKi8KCkxQQ0xBU1NGQUNUT1JZIElDbGFzc0ZhY3RvcnlfQ29uc3RydWN0b3IoUkVGQ0xTSUQgcmNsc2lkKQp7CglJQ2xhc3NGYWN0b3J5SW1wbCogbHBjbGY7CgoJbHBjbGY9IChJQ2xhc3NGYWN0b3J5SW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxzaXplb2YoSUNsYXNzRmFjdG9yeUltcGwpKTsKCWxwY2xmLT5yZWYgPSAxOwoJSUNPTV9WVEJMKGxwY2xmKSA9ICZjbGZ2dDsKCWxwY2xmLT5yY2xzaWQgPSAoQ0xTSUQqKXJjbHNpZDsKCglUUkFDRSgiKCVwKS0+KClcbiIsbHBjbGYpOwoJc2hlbGwzMl9PYmpDb3VudCsrOwoJcmV0dXJuIChMUENMQVNTRkFDVE9SWSlscGNsZjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElDbGFzc0ZhY3RvcnlfUXVlcnlJbnRlcmZhY2UKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuUXVlcnlJbnRlcmZhY2UoCiAgTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdk9iaikKewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCWNoYXIJeHJpaWRbNTBdOwoJV0lORV9TdHJpbmdGcm9tQ0xTSUQoKExQQ0xTSUQpcmlpZCx4cmlpZCk7CglUUkFDRSgiKCVwKS0+KFxuXHRJSUQ6XHQlcylcbiIsVGhpcyx4cmlpZCk7CgoJKnBwdk9iaiA9IE5VTEw7CgoJaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSkgICAgICAgICAgLypJVW5rbm93biovCgl7ICpwcHZPYmogPSBUaGlzOyAKCX0KCWVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lDbGFzc0ZhY3RvcnkpKSAgLypJQ2xhc3NGYWN0b3J5Ki8KCXsgKnBwdk9iaiA9IChJQ2xhc3NGYWN0b3J5KilUaGlzOwoJfSAgIAoKCWlmKCpwcHZPYmopCgl7IElVbmtub3duX0FkZFJlZigoTFBVTktOT1dOKSpwcHZPYmopOyAgCQoJICBUUkFDRSgiLS0gSW50ZXJmYWNlOiAoJXApLT4oJXApXG4iLHBwdk9iaiwqcHB2T2JqKTsKCSAgcmV0dXJuIFNfT0s7Cgl9CglUUkFDRSgiLS0gSW50ZXJmYWNlOiAlcyBFX05PSU5URVJGQUNFXG4iLCB4cmlpZCk7CglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKfSAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUNsYXNzRmFjdG9yeV9BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mbkFkZFJlZihMUENMQVNTRkFDVE9SWSBpZmFjZSkKewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApLT4oY291bnQ9JWx1KVxuIixUaGlzLFRoaXMtPnJlZik7CgoJc2hlbGwzMl9PYmpDb3VudCsrOwoJcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQ2xhc3NGYWN0b3J5X1JlbGVhc2UKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mblJlbGVhc2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpCnsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKS0+KGNvdW50PSVsdSlcbiIsVGhpcyxUaGlzLT5yZWYpOwoKCXNoZWxsMzJfT2JqQ291bnQtLTsKCWlmICghLS0oVGhpcy0+cmVmKSkgCgl7IFRSQUNFKCItLSBkZXN0cm95aW5nIElDbGFzc0ZhY3RvcnkoJXApXG4iLFRoaXMpOwoJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCQlyZXR1cm4gMDsKCX0KCXJldHVybiBUaGlzLT5yZWY7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQ2xhc3NGYWN0b3J5X0NyZWF0ZUluc3RhbmNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mbkNyZWF0ZUluc3RhbmNlKAogIExQQ0xBU1NGQUNUT1JZIGlmYWNlLCBMUFVOS05PV04gcFVua25vd24sIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwT2JqZWN0KQp7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJSVVua25vd24gKnBPYmogPSBOVUxMOwoJSFJFU1VMVCBocmVzOwoJY2hhcgl4cmlpZFs1MF07CgoJV0lORV9TdHJpbmdGcm9tQ0xTSUQoKExQQ0xTSUQpcmlpZCx4cmlpZCk7CglUUkFDRSgiJXAtPiglcCxcblx0SUlEOlx0JXMsJXApXG4iLFRoaXMscFVua25vd24seHJpaWQscHBPYmplY3QpOwoKCSpwcE9iamVjdCA9IE5VTEw7CgkJCglpZihwVW5rbm93bikKCXsKCSAgcmV0dXJuKENMQVNTX0VfTk9BR0dSRUdBVElPTik7Cgl9CgoJaWYgKElzRXF1YWxDTFNJRChUaGlzLT5yY2xzaWQsICZDTFNJRF9TaGVsbERlc2t0b3ApKQoJewoJICBwT2JqID0gKElVbmtub3duICopSVNGX0Rlc2t0b3BfQ29uc3RydWN0b3IoKTsKCX0KCWVsc2UgaWYgKElzRXF1YWxDTFNJRChUaGlzLT5yY2xzaWQsICZDTFNJRF9TaGVsbExpbmspKQoJewoJICBwT2JqID0gKElVbmtub3duICopSVNoZWxsTGlua19Db25zdHJ1Y3RvcihGQUxTRSk7Cgl9IAoJZWxzZQoJewoJICBFUlIoInVua25vd24gSUlEIHJlcXVlc3RlZFxuXHRJSUQ6XHQlc1xuIix4cmlpZCk7CgkgIHJldHVybihFX05PSU5URVJGQUNFKTsKCX0KCQoJaWYgKCFwT2JqKQoJewoJICByZXR1cm4oRV9PVVRPRk1FTU9SWSk7Cgl9CgkgCglocmVzID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UocE9iaixyaWlkLCBwcE9iamVjdCk7CglJVW5rbm93bl9SZWxlYXNlKHBPYmopOwoKCVRSQUNFKCItLSBPYmplY3QgY3JlYXRlZDogKCVwKS0+JXBcbiIsVGhpcywqcHBPYmplY3QpOwoKCXJldHVybiBocmVzOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUNsYXNzRmFjdG9yeV9Mb2NrU2VydmVyCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mbkxvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsIEJPT0wgZkxvY2spCnsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CglUUkFDRSgiJXAtPigweCV4KSwgbm90IGltcGxlbWVudGVkXG4iLFRoaXMsIGZMb2NrKTsKCXJldHVybiBFX05PVElNUEw7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJQ2xhc3NGYWN0b3J5KSBjbGZ2dCA9IAp7CiAgICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogICAgSUNsYXNzRmFjdG9yeV9mblF1ZXJ5SW50ZXJmYWNlLAogICAgSUNsYXNzRmFjdG9yeV9mbkFkZFJlZiwKICBJQ2xhc3NGYWN0b3J5X2ZuUmVsZWFzZSwKICBJQ2xhc3NGYWN0b3J5X2ZuQ3JlYXRlSW5zdGFuY2UsCiAgSUNsYXNzRmFjdG9yeV9mbkxvY2tTZXJ2ZXIKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZWZhdWx0IENsYXNzRmFjdG9yeSBJbXBsZW1lbnRhdGlvbgogKgogKiBTSENyZWF0ZURlZkNsYXNzT2JqZWN0CiAqCiAqIE5PVEVTCiAqICBoZWxwZXIgZnVuY3Rpb24gZm9yIGRsbCdzIHdpdGhvdXQgYSBvd24gY2xhc3NmYWN0b3J5CiAqICBhIGdlbmVyaWMgY2xhc3NmYWN0b3J5IGlzIHJldHVybmVkCiAqICB3aGVuIHRoZSBDcmVhdGVJbnN0YW5jZSBvZiB0aGUgY2YgaXMgY2FsbGVkIHRoZSBjYWxsYmFjayBpcyBleGVjdXRlZAogKi8KdHlwZWRlZiBIUkVTVUxUIChDQUxMQkFDSyAqIExQRk5DUkVBVEVJTlNUQU5DRSkoSVVua25vd24qIHBVbmtPdXRlciwgUkVGSUlEIHJpaWQsIExQVk9JRCogcHB2T2JqZWN0KTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIElDT01fVkZJRUxEKElDbGFzc0ZhY3RvcnkpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKICAgIENMU0lECQkJKnJjbHNpZDsKICAgIExQRk5DUkVBVEVJTlNUQU5DRQkJbHBmbkNJOwogICAgY29uc3QgSUlEICoJCQlyaWlkSW5zdDsKICAgIFVJTlQgKgkJCXBjUmVmRGxsOyAvKiBwb2ludGVyIHRvIHJlZmNvdW50ZXIgaW4gZXh0ZXJuYWwgZGxsICh1Z3Jyci4uLikgKi8KfSBJRGVmQ2xGSW1wbDsKCnN0YXRpYyBJQ09NX1ZUQUJMRShJQ2xhc3NGYWN0b3J5KSBkY2xmdnQ7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElEZWZDbEZfZm5Db25zdHJ1Y3RvcgogKi8KCklDbGFzc0ZhY3RvcnkgKiBJRGVmQ2xGX2ZuQ29uc3RydWN0b3IoTFBGTkNSRUFURUlOU1RBTkNFIGxwZm5DSSwgVUlOVCAqIHBjUmVmRGxsLCBSRUZJSUQgcmlpZEluc3QpCnsKCUlEZWZDbEZJbXBsKiBscGNsZjsKCWNoYXIJeHJpaWRJbnN0WzUwXTsKCglXSU5FX1N0cmluZ0Zyb21DTFNJRCgoTFBDTFNJRClyaWlkSW5zdCx4cmlpZEluc3QpOwoKCWxwY2xmID0gKElEZWZDbEZJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZihJRGVmQ2xGSW1wbCkpOwoJbHBjbGYtPnJlZiA9IDE7CglJQ09NX1ZUQkwobHBjbGYpID0gJmRjbGZ2dDsKCWxwY2xmLT5scGZuQ0kgPSBscGZuQ0k7CglscGNsZi0+cGNSZWZEbGwgPSBwY1JlZkRsbDsKCglpZiAocGNSZWZEbGwpIAoJICAoKnBjUmVmRGxsKSsrOwoKCWxwY2xmLT5yaWlkSW5zdCA9IHJpaWRJbnN0OwoKCVRSQUNFKCIoJXApXG5cdElJRDpcdCVzXG4iLGxwY2xmLCB4cmlpZEluc3QpOwoJc2hlbGwzMl9PYmpDb3VudCsrOwoJcmV0dXJuIChMUENMQVNTRkFDVE9SWSlscGNsZjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElEZWZDbEZfZm5RdWVyeUludGVyZmFjZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEZWZDbEZfZm5RdWVyeUludGVyZmFjZSgKICBMUENMQVNTRkFDVE9SWSBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2T2JqKQp7CglJQ09NX1RISVMoSURlZkNsRkltcGwsaWZhY2UpOwoJY2hhcgl4cmlpZFs1MF07CglXSU5FX1N0cmluZ0Zyb21DTFNJRCgoTFBDTFNJRClyaWlkLHhyaWlkKTsKCVRSQUNFKCIoJXApLT4oXG5cdElJRDpcdCVzKVxuIixUaGlzLHhyaWlkKTsKCgkqcHB2T2JqID0gTlVMTDsKCglpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSAgICAgICAgICAvKklVbmtub3duKi8KCXsgKnBwdk9iaiA9IFRoaXM7IAoJfQoJZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUNsYXNzRmFjdG9yeSkpICAvKklDbGFzc0ZhY3RvcnkqLwoJeyAqcHB2T2JqID0gKElDbGFzc0ZhY3RvcnkqKVRoaXM7Cgl9ICAgCgoJaWYoKnBwdk9iaikKCXsgSVVua25vd25fQWRkUmVmKChMUFVOS05PV04pKnBwdk9iaik7ICAJCgkgIFRSQUNFKCItLSBJbnRlcmZhY2U6ICglcCktPiglcClcbiIscHB2T2JqLCpwcHZPYmopOwoJICByZXR1cm4gU19PSzsKCX0KCVRSQUNFKCItLSBJbnRlcmZhY2U6ICVzIEVfTk9JTlRFUkZBQ0VcbiIsIHhyaWlkKTsKCXJldHVybiBFX05PSU5URVJGQUNFOwp9ICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGVmQ2xGX2ZuQWRkUmVmCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElEZWZDbEZfZm5BZGRSZWYoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGVmQ2xGSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKS0+KGNvdW50PSVsdSlcbiIsVGhpcyxUaGlzLT5yZWYpOwoKCXNoZWxsMzJfT2JqQ291bnQrKzsKCglyZXR1cm4gKysoVGhpcy0+cmVmKTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEZWZDbEZfZm5SZWxlYXNlCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElEZWZDbEZfZm5SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKQp7CglJQ09NX1RISVMoSURlZkNsRkltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCktPihjb3VudD0lbHUpXG4iLFRoaXMsVGhpcy0+cmVmKTsKCglzaGVsbDMyX09iakNvdW50LS07CgoJaWYgKCEtLShUaGlzLT5yZWYpKSAKCXsgCgkgIGlmIChUaGlzLT5wY1JlZkRsbCkgCgkgICAgKCpUaGlzLT5wY1JlZkRsbCktLTsKCgkgIFRSQUNFKCItLSBkZXN0cm95aW5nIElDbGFzc0ZhY3RvcnkoJXApXG4iLFRoaXMpOwoJICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgkgIHJldHVybiAwOwoJfQoJcmV0dXJuIFRoaXMtPnJlZjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEZWZDbEZfZm5DcmVhdGVJbnN0YW5jZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEZWZDbEZfZm5DcmVhdGVJbnN0YW5jZSgKICBMUENMQVNTRkFDVE9SWSBpZmFjZSwgTFBVTktOT1dOIHBVbmtPdXRlciwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2T2JqZWN0KQp7CglJQ09NX1RISVMoSURlZkNsRkltcGwsaWZhY2UpOwoJY2hhcgl4cmlpZFs1MF07CgoJV0lORV9TdHJpbmdGcm9tQ0xTSUQoKExQQ0xTSUQpcmlpZCx4cmlpZCk7CglUUkFDRSgiJXAtPiglcCxcblx0SUlEOlx0JXMsJXApXG4iLFRoaXMscFVua091dGVyLHhyaWlkLHBwdk9iamVjdCk7CgoJKnBwdk9iamVjdCA9IE5VTEw7CgkJCglpZihwVW5rT3V0ZXIpCgkgIHJldHVybihDTEFTU19FX05PQUdHUkVHQVRJT04pOwoKCWlmICggVGhpcy0+cmlpZEluc3Q9PU5VTEwgfHwKCSAgICAgSXNFcXVhbENMU0lEKHJpaWQsIFRoaXMtPnJpaWRJbnN0KSB8fAoJICAgICBJc0VxdWFsQ0xTSUQocmlpZCwgJklJRF9JVW5rbm93bikgKQoJewoJICByZXR1cm4gVGhpcy0+bHBmbkNJKHBVbmtPdXRlciwgcmlpZCwgcHB2T2JqZWN0KTsKCX0KCglFUlIoInVua25vd24gSUlEIHJlcXVlc3RlZFxuXHRJSUQ6XHQlc1xuIix4cmlpZCk7CglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEZWZDbEZfZm5Mb2NrU2VydmVyCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURlZkNsRl9mbkxvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsIEJPT0wgZkxvY2spCnsKCUlDT01fVEhJUyhJRGVmQ2xGSW1wbCxpZmFjZSk7CglUUkFDRSgiJXAtPigweCV4KSwgbm90IGltcGxlbWVudGVkXG4iLFRoaXMsIGZMb2NrKTsKCXJldHVybiBFX05PVElNUEw7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJQ2xhc3NGYWN0b3J5KSBkY2xmdnQgPSAKewogICAgSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKICAgIElEZWZDbEZfZm5RdWVyeUludGVyZmFjZSwKICAgIElEZWZDbEZfZm5BZGRSZWYsCiAgSURlZkNsRl9mblJlbGVhc2UsCiAgSURlZkNsRl9mbkNyZWF0ZUluc3RhbmNlLAogIElEZWZDbEZfZm5Mb2NrU2VydmVyCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ3JlYXRlRGVmQ2xhc3NPYmplY3QJCQlbU0hFTEwzMi43MF0KICovCkhSRVNVTFQgV0lOQVBJIFNIQ3JlYXRlRGVmQ2xhc3NPYmplY3QoCglSRUZJSUQJcmlpZCwJCQkJCglMUFZPSUQqCXBwdiwJCglMUEZOQ1JFQVRFSU5TVEFOQ0UgbHBmbkNJLAkvKiBjcmVhdGUgaW5zdGFuY2UgY2FsbGJhY2sgZW50cnkgKi8KCVVJTlQJKnBjUmVmRGxsLAkJLyogcmVmIGNvdW50IG9mIHRoZSBkbGwgKi8KCVJFRklJRAlyaWlkSW5zdCkJCS8qIG9wdGlvbmFsIGludGVyZmFjZSB0byB0aGUgaW5zdGFuY2UgKi8KewoKCWNoYXIgeHJpaWRbNTBdLHhyaWlkSW5zdFs1MF07CglXSU5FX1N0cmluZ0Zyb21DTFNJRCgoTFBDTFNJRClyaWlkLHhyaWlkKTsKCVdJTkVfU3RyaW5nRnJvbUNMU0lEKChMUENMU0lEKXJpaWRJbnN0LHhyaWlkSW5zdCk7CgoJVFJBQ0UoIlxuXHRJSUQ6XHQlcyAlcCAlcCAlcCBcblx0SUlESW5zOlx0JXNcbiIsCgl4cmlpZCwgcHB2LCBscGZuQ0ksIHBjUmVmRGxsLCB4cmlpZEluc3QpOwoKCWlmICggSXNFcXVhbENMU0lEKHJpaWQsICZJSURfSUNsYXNzRmFjdG9yeSkgKQoJewoJICBJQ2xhc3NGYWN0b3J5ICogcGNmID0gSURlZkNsRl9mbkNvbnN0cnVjdG9yKGxwZm5DSSwgcGNSZWZEbGwsIHJpaWRJbnN0KTsKCSAgaWYgKHBjZikKCSAgewoJICAgICpwcHYgPSBwY2Y7CgkgICAgcmV0dXJuIE5PRVJST1I7CgkgIH0KCSAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7Cgl9CglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoK