LyoKICoJaGFuZGxpbmcgb2YgU0hFTEwzMi5ETEwgT0xFLU9iamVjdHMKICoKICoJQ29weXJpZ2h0IDE5OTcJTWFyY3VzIE1laXNzbmVyCiAqCUNvcHlyaWdodCAxOTk4CUp1ZXJnZW4gU2NobWllZCAgPGp1ZXJnZW4uc2NobWllZEBtZXRyb25ldC5kZT4KICoKICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNobGd1aWQuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKI2luY2x1ZGUgInNoZWxsMzJfbWFpbi5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHNoZWxsKTsKCkRXT1JEIFdJTkFQSSBTSENMU0lERnJvbVN0cmluZ0EgKExQU1RSIGNsc2lkLCBDTFNJRCAqaWQpOwpleHRlcm4gSVNoZWxsRm9sZGVyICogSVNoZWxsRm9sZGVyX0NvbnN0cnVjdG9yKAoJSVNoZWxsRm9sZGVyICogcHNmLAoJTFBJVEVNSURMSVNUIHBpZGwpOwpleHRlcm4gSFJFU1VMVCBJRlNGb2xkZXJfQ29uc3RydWN0b3IoCglJVW5rbm93biAqIHBVbmtPdXRlciwKCVJFRklJRCByaWlkLAoJTFBWT0lEICogcHB2KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ29DcmVhdGVJbnN0YW5jZSBbU0hFTEwzMi4xMDJdCiAqIAogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KTFJFU1VMVCBXSU5BUEkgU0hDb0NyZWF0ZUluc3RhbmNlKAoJTFBTVFIgYWNsc2lkLAoJUkVGQ0xTSUQgY2xzaWQsCglJVW5rbm93biAqIHVua25vd25vdXRlciwKCVJFRklJRCByZWZpaWQsCglMUFZPSUQgKnBwdikKewoJRFdPUkQJaHJlczsKCUlJRAlpaWQ7CglDTFNJRCAqIG15Y2xzaWQgPSAoQ0xTSUQqKWNsc2lkOwoJCglpZiAoIWNsc2lkKQoJewoJICBpZiAoIWFjbHNpZCkgcmV0dXJuIFJFR0RCX0VfQ0xBU1NOT1RSRUc7CgkgIFNIQ0xTSURGcm9tU3RyaW5nQShhY2xzaWQsICZpaWQpOwoJICBteWNsc2lkID0gJmlpZDsKCX0KCglUUkFDRSgiKCVwLFxuXHRDTFNJRDpcdCVzLCB1bms6JXBcblx0SUlEOlx0JXMsJXApXG4iLAoJCWFjbHNpZCxkZWJ1Z3N0cl9ndWlkKG15Y2xzaWQpLHVua25vd25vdXRlcixkZWJ1Z3N0cl9ndWlkKHJlZmlpZCkscHB2KTsKCglpZiBJc0VxdWFsQ0xTSUQobXljbHNpZCwgJkNMU0lEX1NoZWxsRlNGb2xkZXIpCgl7CgkgIGhyZXMgPSBJRlNGb2xkZXJfQ29uc3RydWN0b3IodW5rbm93bm91dGVyLCByZWZpaWQsIHBwdik7Cgl9CgllbHNlCgl7CgkgIGhyZXMgPSBDb0NyZWF0ZUluc3RhbmNlKG15Y2xzaWQsIHVua25vd25vdXRlciwgQ0xTQ1RYX0lOUFJPQ19TRVJWRVIsIHJlZmlpZCwgcHB2KTsKCX0KCQoJaWYoaHJlcyE9U19PSykKCXsKCSAgRVJSKCJmYWlsZWQgKDB4JTA4bHgpIHRvIGNyZWF0ZSBcblx0Q0xTSUQ6XHQlc1xuXHRJSUQ6XHQlc1xuIiwKICAgICAgICAgICAgICBocmVzLCBkZWJ1Z3N0cl9ndWlkKG15Y2xzaWQpLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCkpOwoJICBFUlIoImNsYXNzIG5vdCBmb3VuZCBpbiByZWdpc3RyeVxuIik7Cgl9CgoJVFJBQ0UoIi0tIGluc3RhbmNlOiAlcFxuIiwqcHB2KTsKCXJldHVybiBocmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEVMTDMyX0RsbEdldENsYXNzT2JqZWN0ICAgW1NIRUxMMzIuMTI4XQogKi8KSFJFU1VMVCBXSU5BUEkgU0hFTEwzMl9EbGxHZXRDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsTFBWT0lEICpwcHYpCnsJSFJFU1VMVAlocmVzID0gRV9PVVRPRk1FTU9SWTsKCUxQQ0xBU1NGQUNUT1JZIGxwY2xmOwoKCVRSQUNFKCJcblx0Q0xTSUQ6XHQlcyxcblx0SUlEOlx0JXNcbiIsZGVidWdzdHJfZ3VpZChyY2xzaWQpLGRlYnVnc3RyX2d1aWQoaWlkKSk7CgkKCSpwcHYgPSBOVUxMOwoKCWlmKElzRXF1YWxDTFNJRChyY2xzaWQsICZDTFNJRF9TaGVsbERlc2t0b3ApfHwgCgkgICBJc0VxdWFsQ0xTSUQocmNsc2lkLCAmQ0xTSURfU2hlbGxMaW5rKSkKCXsKCSAgbHBjbGYgPSBJQ2xhc3NGYWN0b3J5X0NvbnN0cnVjdG9yKCByY2xzaWQgKTsKCgkgIGlmKGxwY2xmKSAKCSAgewoJICAgIGhyZXMgPSBJQ2xhc3NGYWN0b3J5X1F1ZXJ5SW50ZXJmYWNlKGxwY2xmLGlpZCwgcHB2KTsKCSAgICBJQ2xhc3NGYWN0b3J5X1JlbGVhc2UobHBjbGYpOwoJICB9Cgl9CgllbHNlCgl7CgkgIFdBUk4oIi0tIENMU0lEIG5vdCBmb3VuZFxuIik7CgkgIGhyZXMgPSBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFOwoJfQoJVFJBQ0UoIi0tIHBvaW50ZXIgdG8gY2xhc3MgZmFjdG9yeTogJXBcbiIsKnBwdik7CglyZXR1cm4gaHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDTFNJREZyb21TdHJpbmcJCQkJW1NIRUxMMzIuMTQ3XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KRFdPUkQgV0lOQVBJIFNIQ0xTSURGcm9tU3RyaW5nQSAoTFBTVFIgY2xzaWQsIENMU0lEICppZCkKewogICAgV0NIQVIgYnVmZmVyWzQwXTsKICAgIFRSQUNFKCIoJXAoJXMpICVwKVxuIiwgY2xzaWQsIGNsc2lkLCBpZCk7CiAgICBpZiAoIU11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgY2xzaWQsIC0xLCBidWZmZXIsIHNpemVvZihidWZmZXIpL3NpemVvZihXQ0hBUikgKSkKICAgICAgICByZXR1cm4gQ09fRV9DTEFTU1NUUklORzsKICAgIHJldHVybiBDTFNJREZyb21TdHJpbmcoIGJ1ZmZlciwgaWQgKTsKfQpEV09SRCBXSU5BUEkgU0hDTFNJREZyb21TdHJpbmdXIChMUFdTVFIgY2xzaWQsIENMU0lEICppZCkKewoJVFJBQ0UoIiglcCglcykgJXApXG4iLCBjbHNpZCwgZGVidWdzdHJfdyhjbHNpZCksIGlkKTsKCXJldHVybiBDTFNJREZyb21TdHJpbmcoY2xzaWQsIGlkKTsgCn0KRFdPUkQgV0lOQVBJIFNIQ0xTSURGcm9tU3RyaW5nQVcgKExQVk9JRCBjbHNpZCwgQ0xTSUQgKmlkKQp7CglpZiAoU0hFTExfT3NJc1VuaWNvZGUoKSkKCSAgcmV0dXJuIFNIQ0xTSURGcm9tU3RyaW5nVyAoY2xzaWQsIGlkKTsKCXJldHVybiBTSENMU0lERnJvbVN0cmluZ0EgKGNsc2lkLCBpZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJIFNIR2V0TWFsbG9jCQkJW1NIRUxMMzIuMjIwXQogKiByZXR1cm5zIHRoZSBpbnRlcmZhY2UgdG8gc2hlbGwgbWFsbG9jLgogKgogKiBbU0RLIGhlYWRlciB3aW45NS9zaGxvYmouaDoKICogZXF1aXZhbGVudCB0bzogICNkZWZpbmUgU0hHZXRNYWxsb2MocHBtZW0pICAgQ29HZXRNYWxsb2MoTUVNQ1RYX1RBU0ssIHBwbWVtKQogKiBdCiAqIFdoYXQgd2UgYXJlIGN1cnJlbnRseSBkb2luZyBpcyBub3QgdmVyeSB3cm9uZywgc2luY2Ugd2UgYWx3YXlzIHVzZSB0aGUgc2FtZQogKiBoZWFwIChQcm9jZXNzSGVhcCkuCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRNYWxsb2MoTFBNQUxMT0MgKmxwbWFsKSAKewoJVFJBQ0UoIiglcClcbiIsIGxwbWFsKTsKCXJldHVybiBDb0dldE1hbGxvYyhNRU1DVFhfVEFTSywgbHBtYWwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEdldERlc2t0b3BGb2xkZXIJCQlbU0hFTEwzMi4yMTZdCiAqLwpMUFNIRUxMRk9MREVSIHBkZXNrdG9wZm9sZGVyPU5VTEw7CgpEV09SRCBXSU5BUEkgU0hHZXREZXNrdG9wRm9sZGVyKElTaGVsbEZvbGRlciAqKnBzZikKewoJSFJFU1VMVAlocmVzID0gU19PSzsKCUxQQ0xBU1NGQUNUT1JZIGxwY2xmOwoJVFJBQ0UoIiVwLT4oJXApXG4iLHBzZiwqcHNmKTsKCgkqcHNmPU5VTEw7CgoJaWYgKCFwZGVza3RvcGZvbGRlcikgCgl7CgkgIGxwY2xmID0gSUNsYXNzRmFjdG9yeV9Db25zdHJ1Y3RvcigmQ0xTSURfU2hlbGxEZXNrdG9wKTsKCSAgaWYobHBjbGYpIAoJICB7CgkgICAgaHJlcyA9IElDbGFzc0ZhY3RvcnlfQ3JlYXRlSW5zdGFuY2UobHBjbGYsTlVMTCwoUkVGSUlEKSZJSURfSVNoZWxsRm9sZGVyLCAodm9pZCopJnBkZXNrdG9wZm9sZGVyKTsKCSAgICBJQ2xhc3NGYWN0b3J5X1JlbGVhc2UobHBjbGYpOwoJICB9ICAKCX0KCQoJaWYgKHBkZXNrdG9wZm9sZGVyKSAKCXsKCSAgLyogZXZlbiBpZiB3ZSBjcmVhdGUgdGhlIGZvbGRlciwgYWRkIGEgcmVmIHNvIHRoZSBhcHBsaWNhdGlvbiBjYW60dCBkZXN0cm95IHRoZSBmb2xkZXIqLwoJICBJU2hlbGxGb2xkZXJfQWRkUmVmKHBkZXNrdG9wZm9sZGVyKTsKCSAgKnBzZiA9IHBkZXNrdG9wZm9sZGVyOwoJfQoKCVRSQUNFKCItLSAlcC0+KCVwKVxuIixwc2YsICpwc2YpOwoJcmV0dXJuIGhyZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICBJQ2xhc3NGYWN0b3J5IEltcGxlbWVudGF0aW9uCiovCgp0eXBlZGVmIHN0cnVjdAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElDbGFzc0ZhY3RvcnkpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKICAgIENMU0lECQkJKnJjbHNpZDsKfSBJQ2xhc3NGYWN0b3J5SW1wbDsKCnN0YXRpYyBJQ09NX1ZUQUJMRShJQ2xhc3NGYWN0b3J5KSBjbGZ2dDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUNsYXNzRmFjdG9yeV9Db25zdHJ1Y3RvcgogKi8KCkxQQ0xBU1NGQUNUT1JZIElDbGFzc0ZhY3RvcnlfQ29uc3RydWN0b3IoUkVGQ0xTSUQgcmNsc2lkKQp7CglJQ2xhc3NGYWN0b3J5SW1wbCogbHBjbGY7CgoJbHBjbGY9IChJQ2xhc3NGYWN0b3J5SW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxzaXplb2YoSUNsYXNzRmFjdG9yeUltcGwpKTsKCWxwY2xmLT5yZWYgPSAxOwoJSUNPTV9WVEJMKGxwY2xmKSA9ICZjbGZ2dDsKCWxwY2xmLT5yY2xzaWQgPSAoQ0xTSUQqKXJjbHNpZDsKCglUUkFDRSgiKCVwKS0+KClcbiIsbHBjbGYpOwoJSW50ZXJsb2NrZWRJbmNyZW1lbnQoJnNoZWxsMzJfT2JqQ291bnQpOwoJcmV0dXJuIChMUENMQVNTRkFDVE9SWSlscGNsZjsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElDbGFzc0ZhY3RvcnlfUXVlcnlJbnRlcmZhY2UKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuUXVlcnlJbnRlcmZhY2UoCiAgTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdk9iaikKewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApLT4oXG5cdElJRDpcdCVzKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkpOwoKCSpwcHZPYmogPSBOVUxMOwoKCWlmKElzRXF1YWxJSUQocmlpZCwgJklJRF9JVW5rbm93bikpICAgICAgICAgIC8qSVVua25vd24qLwoJeyAqcHB2T2JqID0gVGhpczsgCgl9CgllbHNlIGlmKElzRXF1YWxJSUQocmlpZCwgJklJRF9JQ2xhc3NGYWN0b3J5KSkgIC8qSUNsYXNzRmFjdG9yeSovCgl7ICpwcHZPYmogPSAoSUNsYXNzRmFjdG9yeSopVGhpczsKCX0gICAKCglpZigqcHB2T2JqKQoJeyBJVW5rbm93bl9BZGRSZWYoKExQVU5LTk9XTikqcHB2T2JqKTsgIAkKCSAgVFJBQ0UoIi0tIEludGVyZmFjZTogKCVwKS0+KCVwKVxuIixwcHZPYmosKnBwdk9iaik7CgkgIHJldHVybiBTX09LOwoJfQoJVFJBQ0UoIi0tIEludGVyZmFjZTogJXMgRV9OT0lOVEVSRkFDRVxuIiwgZGVidWdzdHJfZ3VpZChyaWlkKSk7CglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKfSAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUNsYXNzRmFjdG9yeV9BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mbkFkZFJlZihMUENMQVNTRkFDVE9SWSBpZmFjZSkKewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApLT4oY291bnQ9JWx1KVxuIixUaGlzLFRoaXMtPnJlZik7CgoJSW50ZXJsb2NrZWRJbmNyZW1lbnQoJnNoZWxsMzJfT2JqQ291bnQpOwoJcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUNsYXNzRmFjdG9yeV9SZWxlYXNlCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKQp7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCktPihjb3VudD0lbHUpXG4iLFRoaXMsVGhpcy0+cmVmKTsKCglJbnRlcmxvY2tlZERlY3JlbWVudCgmc2hlbGwzMl9PYmpDb3VudCk7CglpZiAoIUludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpKSAKCXsKCSAgVFJBQ0UoIi0tIGRlc3Ryb3lpbmcgSUNsYXNzRmFjdG9yeSglcClcbiIsVGhpcyk7CgkgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCSAgcmV0dXJuIDA7Cgl9CglyZXR1cm4gVGhpcy0+cmVmOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUNsYXNzRmFjdG9yeV9DcmVhdGVJbnN0YW5jZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5DcmVhdGVJbnN0YW5jZSgKICBMUENMQVNTRkFDVE9SWSBpZmFjZSwgTFBVTktOT1dOIHBVbmtub3duLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcE9iamVjdCkKewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCUlVbmtub3duICpwT2JqID0gTlVMTDsKCUhSRVNVTFQgaHJlczsKCglUUkFDRSgiJXAtPiglcCxcblx0SUlEOlx0JXMsJXApXG4iLFRoaXMscFVua25vd24sZGVidWdzdHJfZ3VpZChyaWlkKSxwcE9iamVjdCk7CgoJKnBwT2JqZWN0ID0gTlVMTDsKCQkKCWlmKHBVbmtub3duKQoJewoJICByZXR1cm4oQ0xBU1NfRV9OT0FHR1JFR0FUSU9OKTsKCX0KCglpZiAoSXNFcXVhbENMU0lEKFRoaXMtPnJjbHNpZCwgJkNMU0lEX1NoZWxsRGVza3RvcCkpCgl7CgkgIHBPYmogPSAoSVVua25vd24gKilJU0ZfRGVza3RvcF9Db25zdHJ1Y3RvcigpOwoJfQoJZWxzZSBpZiAoSXNFcXVhbENMU0lEKFRoaXMtPnJjbHNpZCwgJkNMU0lEX1NoZWxsTGluaykpCgl7CgkgIHBPYmogPSAoSVVua25vd24gKilJU2hlbGxMaW5rX0NvbnN0cnVjdG9yKEZBTFNFKTsKCX0gCgllbHNlCgl7CgkgIEVSUigidW5rbm93biBJSUQgcmVxdWVzdGVkXG5cdElJRDpcdCVzXG4iLGRlYnVnc3RyX2d1aWQocmlpZCkpOwoJICByZXR1cm4oRV9OT0lOVEVSRkFDRSk7Cgl9CgkKCWlmICghcE9iaikKCXsKCSAgcmV0dXJuKEVfT1VUT0ZNRU1PUlkpOwoJfQoJIAoJaHJlcyA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHBPYmoscmlpZCwgcHBPYmplY3QpOwoJSVVua25vd25fUmVsZWFzZShwT2JqKTsKCglUUkFDRSgiLS0gT2JqZWN0IGNyZWF0ZWQ6ICglcCktPiVwXG4iLFRoaXMsKnBwT2JqZWN0KTsKCglyZXR1cm4gaHJlczsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElDbGFzc0ZhY3RvcnlfTG9ja1NlcnZlcgogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5Mb2NrU2VydmVyKExQQ0xBU1NGQUNUT1JZIGlmYWNlLCBCT09MIGZMb2NrKQp7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJVFJBQ0UoIiVwLT4oMHgleCksIG5vdCBpbXBsZW1lbnRlZFxuIixUaGlzLCBmTG9jayk7CglyZXR1cm4gRV9OT1RJTVBMOwp9CgpzdGF0aWMgSUNPTV9WVEFCTEUoSUNsYXNzRmFjdG9yeSkgY2xmdnQgPSAKewogICAgSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKICAgIElDbGFzc0ZhY3RvcnlfZm5RdWVyeUludGVyZmFjZSwKICAgIElDbGFzc0ZhY3RvcnlfZm5BZGRSZWYsCiAgSUNsYXNzRmFjdG9yeV9mblJlbGVhc2UsCiAgSUNsYXNzRmFjdG9yeV9mbkNyZWF0ZUluc3RhbmNlLAogIElDbGFzc0ZhY3RvcnlfZm5Mb2NrU2VydmVyCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGVmYXVsdCBDbGFzc0ZhY3RvcnkgSW1wbGVtZW50YXRpb24KICoKICogU0hDcmVhdGVEZWZDbGFzc09iamVjdAogKgogKiBOT1RFUwogKiAgaGVscGVyIGZ1bmN0aW9uIGZvciBkbGwncyB3aXRob3V0IGEgb3duIGNsYXNzZmFjdG9yeQogKiAgYSBnZW5lcmljIGNsYXNzZmFjdG9yeSBpcyByZXR1cm5lZAogKiAgd2hlbiB0aGUgQ3JlYXRlSW5zdGFuY2Ugb2YgdGhlIGNmIGlzIGNhbGxlZCB0aGUgY2FsbGJhY2sgaXMgZXhlY3V0ZWQKICovCnR5cGVkZWYgSFJFU1VMVCAoQ0FMTEJBQ0sgKiBMUEZOQ1JFQVRFSU5TVEFOQ0UpKElVbmtub3duKiBwVW5rT3V0ZXIsIFJFRklJRCByaWlkLCBMUFZPSUQqIHBwdk9iamVjdCk7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBJQ09NX1ZGSUVMRChJQ2xhc3NGYWN0b3J5KTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICBDTFNJRAkJCSpyY2xzaWQ7CiAgICBMUEZOQ1JFQVRFSU5TVEFOQ0UJCWxwZm5DSTsKICAgIGNvbnN0IElJRCAqCQkJcmlpZEluc3Q7CiAgICBVTE9ORyAqCQkJcGNSZWZEbGw7IC8qIHBvaW50ZXIgdG8gcmVmY291bnRlciBpbiBleHRlcm5hbCBkbGwgKHVncnJyLi4uKSAqLwp9IElEZWZDbEZJbXBsOwoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIGRjbGZ2dDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSURlZkNsRl9mbkNvbnN0cnVjdG9yCiAqLwoKSUNsYXNzRmFjdG9yeSAqIElEZWZDbEZfZm5Db25zdHJ1Y3RvcihMUEZOQ1JFQVRFSU5TVEFOQ0UgbHBmbkNJLCBQTE9ORyBwY1JlZkRsbCwgUkVGSUlEIHJpaWRJbnN0KQp7CglJRGVmQ2xGSW1wbCogbHBjbGY7CgoJbHBjbGYgPSAoSURlZkNsRkltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKElEZWZDbEZJbXBsKSk7CglscGNsZi0+cmVmID0gMTsKCUlDT01fVlRCTChscGNsZikgPSAmZGNsZnZ0OwoJbHBjbGYtPmxwZm5DSSA9IGxwZm5DSTsKCWxwY2xmLT5wY1JlZkRsbCA9IHBjUmVmRGxsOwoKCWlmIChwY1JlZkRsbCkgSW50ZXJsb2NrZWRJbmNyZW1lbnQocGNSZWZEbGwpOwoJbHBjbGYtPnJpaWRJbnN0ID0gcmlpZEluc3Q7CgoJVFJBQ0UoIiglcClcblx0SUlEOlx0JXNcbiIsbHBjbGYsIGRlYnVnc3RyX2d1aWQocmlpZEluc3QpKTsKCUludGVybG9ja2VkSW5jcmVtZW50KCZzaGVsbDMyX09iakNvdW50KTsKCXJldHVybiAoTFBDTEFTU0ZBQ1RPUlkpbHBjbGY7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJRGVmQ2xGX2ZuUXVlcnlJbnRlcmZhY2UKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGVmQ2xGX2ZuUXVlcnlJbnRlcmZhY2UoCiAgTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdk9iaikKewoJSUNPTV9USElTKElEZWZDbEZJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwKS0+KFxuXHRJSUQ6XHQlcylcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCgkqcHB2T2JqID0gTlVMTDsKCglpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSAgICAgICAgICAvKklVbmtub3duKi8KCXsgKnBwdk9iaiA9IFRoaXM7IAoJfQoJZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUNsYXNzRmFjdG9yeSkpICAvKklDbGFzc0ZhY3RvcnkqLwoJeyAqcHB2T2JqID0gKElDbGFzc0ZhY3RvcnkqKVRoaXM7Cgl9ICAgCgoJaWYoKnBwdk9iaikKCXsgSVVua25vd25fQWRkUmVmKChMUFVOS05PV04pKnBwdk9iaik7ICAJCgkgIFRSQUNFKCItLSBJbnRlcmZhY2U6ICglcCktPiglcClcbiIscHB2T2JqLCpwcHZPYmopOwoJICByZXR1cm4gU19PSzsKCX0KCVRSQUNFKCItLSBJbnRlcmZhY2U6ICVzIEVfTk9JTlRFUkZBQ0VcbiIsIGRlYnVnc3RyX2d1aWQocmlpZCkpOwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0gIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEZWZDbEZfZm5BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURlZkNsRl9mbkFkZFJlZihMUENMQVNTRkFDVE9SWSBpZmFjZSkKewoJSUNPTV9USElTKElEZWZDbEZJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApLT4oY291bnQ9JWx1KVxuIixUaGlzLFRoaXMtPnJlZik7CgoJSW50ZXJsb2NrZWRJbmNyZW1lbnQoJnNoZWxsMzJfT2JqQ291bnQpOwoJcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURlZkNsRl9mblJlbGVhc2UKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURlZkNsRl9mblJlbGVhc2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGVmQ2xGSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKS0+KGNvdW50PSVsdSlcbiIsVGhpcyxUaGlzLT5yZWYpOwoKCUludGVybG9ja2VkRGVjcmVtZW50KCZzaGVsbDMyX09iakNvdW50KTsKCglpZiAoIUludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpKSAKCXsgCgkgIGlmIChUaGlzLT5wY1JlZkRsbCkgSW50ZXJsb2NrZWREZWNyZW1lbnQoVGhpcy0+cGNSZWZEbGwpOwoKCSAgVFJBQ0UoIi0tIGRlc3Ryb3lpbmcgSUNsYXNzRmFjdG9yeSglcClcbiIsVGhpcyk7CgkgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCSAgcmV0dXJuIDA7Cgl9CglyZXR1cm4gVGhpcy0+cmVmOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURlZkNsRl9mbkNyZWF0ZUluc3RhbmNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURlZkNsRl9mbkNyZWF0ZUluc3RhbmNlKAogIExQQ0xBU1NGQUNUT1JZIGlmYWNlLCBMUFVOS05PV04gcFVua091dGVyLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHZPYmplY3QpCnsKCUlDT01fVEhJUyhJRGVmQ2xGSW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiVwLT4oJXAsXG5cdElJRDpcdCVzLCVwKVxuIixUaGlzLHBVbmtPdXRlcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwdk9iamVjdCk7CgoJKnBwdk9iamVjdCA9IE5VTEw7CgkJCglpZihwVW5rT3V0ZXIpCgkgIHJldHVybihDTEFTU19FX05PQUdHUkVHQVRJT04pOwoKCWlmICggVGhpcy0+cmlpZEluc3Q9PU5VTEwgfHwKCSAgICAgSXNFcXVhbENMU0lEKHJpaWQsIFRoaXMtPnJpaWRJbnN0KSB8fAoJICAgICBJc0VxdWFsQ0xTSUQocmlpZCwgJklJRF9JVW5rbm93bikgKQoJewoJICByZXR1cm4gVGhpcy0+bHBmbkNJKHBVbmtPdXRlciwgcmlpZCwgcHB2T2JqZWN0KTsKCX0KCglFUlIoInVua25vd24gSUlEIHJlcXVlc3RlZFxuXHRJSUQ6XHQlc1xuIixkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCXJldHVybiBFX05PSU5URVJGQUNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURlZkNsRl9mbkxvY2tTZXJ2ZXIKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGVmQ2xGX2ZuTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSwgQk9PTCBmTG9jaykKewoJSUNPTV9USElTKElEZWZDbEZJbXBsLGlmYWNlKTsKCVRSQUNFKCIlcC0+KDB4JXgpLCBub3QgaW1wbGVtZW50ZWRcbiIsVGhpcywgZkxvY2spOwoJcmV0dXJuIEVfTk9USU1QTDsKfQoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIGRjbGZ2dCA9IAp7CiAgICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogICAgSURlZkNsRl9mblF1ZXJ5SW50ZXJmYWNlLAogICAgSURlZkNsRl9mbkFkZFJlZiwKICBJRGVmQ2xGX2ZuUmVsZWFzZSwKICBJRGVmQ2xGX2ZuQ3JlYXRlSW5zdGFuY2UsCiAgSURlZkNsRl9mbkxvY2tTZXJ2ZXIKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDcmVhdGVEZWZDbGFzc09iamVjdAkJCVtTSEVMTDMyLjcwXQogKi8KSFJFU1VMVCBXSU5BUEkgU0hDcmVhdGVEZWZDbGFzc09iamVjdCgKCVJFRklJRAlyaWlkLAkJCQkKCUxQVk9JRCoJcHB2LAkKCUxQRk5DUkVBVEVJTlNUQU5DRSBscGZuQ0ksCS8qIFtpbl0gY3JlYXRlIGluc3RhbmNlIGNhbGxiYWNrIGVudHJ5ICovCglQTE9ORwlwY1JlZkRsbCwJCS8qIFtpbi9vdXRdIHJlZiBjb3VudCBvZiB0aGUgZGxsICovCglSRUZJSUQJcmlpZEluc3QpCQkvKiBbaW5dIG9wdGlvbmFsIGludGVyZmFjZSB0byB0aGUgaW5zdGFuY2UgKi8KewoJVFJBQ0UoIlxuXHRJSUQ6XHQlcyAlcCAlcCAlcCBcblx0SUlESW5zOlx0JXNcbiIsCiAgICAgICAgICAgICAgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2LCBscGZuQ0ksIHBjUmVmRGxsLCBkZWJ1Z3N0cl9ndWlkKHJpaWRJbnN0KSk7CgoJaWYgKCBJc0VxdWFsQ0xTSUQocmlpZCwgJklJRF9JQ2xhc3NGYWN0b3J5KSApCgl7CgkgIElDbGFzc0ZhY3RvcnkgKiBwY2YgPSBJRGVmQ2xGX2ZuQ29uc3RydWN0b3IobHBmbkNJLCBwY1JlZkRsbCwgcmlpZEluc3QpOwoJICBpZiAocGNmKQoJICB7CgkgICAgKnBwdiA9IHBjZjsKCSAgICByZXR1cm4gTk9FUlJPUjsKCSAgfQoJICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCX0KCXJldHVybiBFX05PSU5URVJGQUNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgRHJhZ0FjY2VwdEZpbGVzCQlbU0hFTEwzMi41NF0KICovCnZvaWQgV0lOQVBJIERyYWdBY2NlcHRGaWxlcyhIV05EIGhXbmQsIEJPT0wgYikKewoJTE9ORyBleHN0eWxlOwogIAoJaWYoICFJc1dpbmRvdyhoV25kKSApIHJldHVybjsKCWV4c3R5bGUgPSBHZXRXaW5kb3dMb25nQShoV25kLEdXTF9FWFNUWUxFKTsKCWlmIChiKQoJICBleHN0eWxlIHw9IFdTX0VYX0FDQ0VQVEZJTEVTOwoJZWxzZQoJICBleHN0eWxlICY9IH5XU19FWF9BQ0NFUFRGSUxFUzsKCVNldFdpbmRvd0xvbmdBKGhXbmQsR1dMX0VYU1RZTEUsZXhzdHlsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERyYWdGaW5pc2gJCVtTSEVMTDMyLjgwXQogKi8Kdm9pZCBXSU5BUEkgRHJhZ0ZpbmlzaChIRFJPUCBoKQp7CglUUkFDRSgiXG4iKTsKCUdsb2JhbEZyZWUoKEhHTE9CQUwpaCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERyYWdRdWVyeVBvaW50CQlbU0hFTEwzMi4xMzVdCiAqLwpCT09MIFdJTkFQSSBEcmFnUXVlcnlQb2ludChIRFJPUCBoRHJvcCwgUE9JTlQgKnApCnsKICAgICAgICBEUk9QRklMRVMgKmxwRHJvcEZpbGVTdHJ1Y3Q7CglCT09MIGJSZXQ7CgoJVFJBQ0UoIlxuIik7CgoJbHBEcm9wRmlsZVN0cnVjdCA9IChEUk9QRklMRVMgKikgR2xvYmFsTG9jayhoRHJvcCk7CgogICAgICAgICpwID0gbHBEcm9wRmlsZVN0cnVjdC0+cHQ7CgliUmV0ID0gbHBEcm9wRmlsZVN0cnVjdC0+Zk5DOwogIAoJR2xvYmFsVW5sb2NrKGhEcm9wKTsKCXJldHVybiBiUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgRHJhZ1F1ZXJ5RmlsZUEJCVtTSEVMTDMyLjgxXSBbc2hlbGwzMi44Ml0KICovClVJTlQgV0lOQVBJIERyYWdRdWVyeUZpbGVBKAoJSERST1AgaERyb3AsCglVSU5UIGxGaWxlLAoJTFBTVFIgbHBzekZpbGUsCglVSU5UIGxMZW5ndGgpCnsKCUxQU1RSIGxwRHJvcDsKCVVJTlQgaSA9IDA7CglEUk9QRklMRVMgKmxwRHJvcEZpbGVTdHJ1Y3QgPSAoRFJPUEZJTEVTICopIEdsb2JhbExvY2soaERyb3ApOwogICAgCglUUkFDRSgiKCUwOHgsICV4LCAlcCwgJXUpXG4iLAloRHJvcCxsRmlsZSxscHN6RmlsZSxsTGVuZ3RoKTsKICAgIAoJaWYoIWxwRHJvcEZpbGVTdHJ1Y3QpIGdvdG8gZW5kOwoKCWxwRHJvcCA9IChMUFNUUikgbHBEcm9wRmlsZVN0cnVjdCArIGxwRHJvcEZpbGVTdHJ1Y3QtPnBGaWxlczsKCgl3aGlsZSAoaSsrIDwgbEZpbGUpCgl7CgkgIHdoaWxlICgqbHBEcm9wKyspOyAvKiBza2lwIGZpbGVuYW1lICovCgkgIGlmICghKmxwRHJvcCkgCgkgIHsKCSAgICBpID0gKGxGaWxlID09IDB4RkZGRkZGRkYpID8gaSA6IDA7IAoJICAgIGdvdG8gZW5kOwoJICB9Cgl9CiAgICAKCWkgPSBzdHJsZW4obHBEcm9wKTsKCWkrKzsKCWlmICghbHBzekZpbGUgKSBnb3RvIGVuZDsgICAvKiBuZWVkZWQgYnVmZmVyIHNpemUgKi8KCWkgPSAobExlbmd0aCA+IGkpID8gaSA6IGxMZW5ndGg7Cglsc3RyY3B5bkEgKGxwc3pGaWxlLCAgbHBEcm9wLCAgaSk7CmVuZDoKCUdsb2JhbFVubG9jayhoRHJvcCk7CglyZXR1cm4gaTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIERyYWdRdWVyeUZpbGVXCQlbc2hlbGwzMi4xMzNdCiAqLwpVSU5UIFdJTkFQSSBEcmFnUXVlcnlGaWxlVygKCUhEUk9QIGhEcm9wLAoJVUlOVCBsRmlsZSwKCUxQV1NUUiBscHN6d0ZpbGUsCglVSU5UIGxMZW5ndGgpCnsKCUxQV1NUUiBscHdEcm9wOwoJVUlOVCBpID0gMDsKCURST1BGSUxFUyAqbHBEcm9wRmlsZVN0cnVjdCA9IChEUk9QRklMRVMgKikgR2xvYmFsTG9jayhoRHJvcCk7CiAgICAKCVRSQUNFKCIoJTA4eCwgJXgsICVwLCAldSlcbiIsIGhEcm9wLGxGaWxlLGxwc3p3RmlsZSxsTGVuZ3RoKTsKICAgIAoJaWYoIWxwRHJvcEZpbGVTdHJ1Y3QpIGdvdG8gZW5kOwoKCWxwd0Ryb3AgPSAoTFBXU1RSKSBscERyb3BGaWxlU3RydWN0ICsgbHBEcm9wRmlsZVN0cnVjdC0+cEZpbGVzOwoKCWkgPSAwOwoJd2hpbGUgKGkrKyA8IGxGaWxlKQoJewoJICB3aGlsZSAoKmxwd0Ryb3ArKyk7IC8qIHNraXAgZmlsZW5hbWUgKi8KCSAgaWYgKCEqbHB3RHJvcCkgCgkgIHsKCSAgICBpID0gKGxGaWxlID09IDB4RkZGRkZGRkYpID8gaSA6IDA7IAoJICAgIGdvdG8gZW5kOwoJICB9Cgl9CiAgICAKCWkgPSBzdHJsZW5XKGxwd0Ryb3ApOwoJaSsrOwoJaWYgKCAhbHBzendGaWxlKSBnb3RvIGVuZDsgICAvKiBuZWVkZWQgYnVmZmVyIHNpemUgKi8KCglpID0gKGxMZW5ndGggPiBpKSA/IGkgOiBsTGVuZ3RoOwoJbHN0cmNweW5XIChscHN6d0ZpbGUsIGxwd0Ryb3AsIGkpOwplbmQ6CglHbG9iYWxVbmxvY2soaERyb3ApOwoJcmV0dXJuIGk7Cn0K