LyoKICogQ29weXJpZ2h0IChjKSAxOTg4LCAxOTkwLCAxOTkzCiAqCVRoZSBSZWdlbnRzIG9mIHRoZSBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICogTW9kaWZpZWQgU3VuIE1hciAxMiAxMDozNDozNCAxOTk1LCBmYWl0aEBjcy51bmMuZWR1LCBmb3IgTGludXgKICovCgovKgogKiBUaGlzIHByb2dyYW0gaXMgbm90IHJlbGF0ZWQgdG8gRGF2aWQgV2FsbCwgd2hvc2UgU3RhbmZvcmQgUGguRC4gdGhlc2lzCiAqIGlzIGVudGl0bGVkICJNZWNoYW5pc21zIGZvciBCcm9hZGNhc3QgYW5kIFNlbGVjdGl2ZSBCcm9hZGNhc3QiLgogKgogKiAxOTk5LTAyLTIyIEFya2FkaXVzeiBNabZraWV3aWN6IDxtaXNpZWtAcGxkLk9SRy5QTD4KICogLSBhZGRlZCBOYXRpdmUgTGFuZ3VhZ2UgU3VwcG9ydAogKgogKi8KCiNpbmNsdWRlIDxzeXMvcGFyYW0uaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSA8c3lzL3Vpby5oPgoKI2luY2x1ZGUgPHBhdGhzLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8cHdkLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8dXRtcC5oPgoKI2luY2x1ZGUgIm5scy5oIgojaW5jbHVkZSAieHN0cm5jcHkuaCIKI2luY2x1ZGUgInR0eW1zZy5oIgojaW5jbHVkZSAicGF0aG5hbWVzLmgiCiNpbmNsdWRlICJjYXJlZnVscHV0Yy5oIgoKdm9pZAltYWtlbXNnIF9fUCgoY2hhciAqKSk7CgojZGVmaW5lCUlHTk9SRVVTRVIJInNsZWVwZXIiCgojaWZuZGVmIE1BWEhPU1ROQU1FTEVOCiMgaWZkZWYgSE9TVF9OQU1FX01BWAojICBkZWZpbmUgTUFYSE9TVE5BTUVMRU4gSE9TVF9OQU1FX01BWAojIGVsc2UKIyAgZGVmaW5lIE1BWEhPU1ROQU1FTEVOIDY0CiMgZW5kaWYKI2VuZGlmCgppbnQgbm9iYW5uZXI7CmludCBtYnVmc2l6ZTsKY2hhciAqbWJ1ZjsKCmNoYXIgKnByb2duYW1lID0gIndhbGwiOwoKaW50Cm1haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KSB7CglleHRlcm4gaW50IG9wdGluZDsKCWludCBjaDsKCXN0cnVjdCBpb3ZlYyBpb3Y7CglzdHJ1Y3QgdXRtcCAqdXRtcHB0cjsKCWNoYXIgKnA7CgljaGFyIGxpbmVbc2l6ZW9mKHV0bXBwdHItPnV0X2xpbmUpICsgMV07CgoJc2V0bG9jYWxlKExDX0FMTCwgIiIpOwogICAgICAgIGJpbmR0ZXh0ZG9tYWluKFBBQ0tBR0UsIExPQ0FMRURJUik7CiAgICAgICAgdGV4dGRvbWFpbihQQUNLQUdFKTsKCglwcm9nbmFtZSA9IGFyZ3ZbMF07CglwID0gc3RycmNocihwcm9nbmFtZSwgJy8nKTsKCWlmIChwKQoJICAgICBwcm9nbmFtZSA9IHArMTsKCgl3aGlsZSAoKGNoID0gZ2V0b3B0KGFyZ2MsIGFyZ3YsICJuIikpICE9IC0xKQoJCXN3aXRjaCAoY2gpIHsKCQljYXNlICduJzoKCQkJLyogdW5kb2Mgb3B0aW9uIGZvciBzaHV0ZG93bjogc3VwcHJlc3MgYmFubmVyICovCgkJCWlmIChnZXRldWlkKCkgPT0gMCkKCQkJCW5vYmFubmVyID0gMTsKCQkJYnJlYWs7CgkJY2FzZSAnPyc6CgkJZGVmYXVsdDoKdXNhZ2U6CgkJCSh2b2lkKWZwcmludGYoc3RkZXJyLCBfKCJ1c2FnZTogJXMgW2ZpbGVdXG4iKSwgcHJvZ25hbWUpOwoJCQlleGl0KDEpOwoJCX0KCWFyZ2MgLT0gb3B0aW5kOwoJYXJndiArPSBvcHRpbmQ7CglpZiAoYXJnYyA+IDEpCgkJZ290byB1c2FnZTsKCgltYWtlbXNnKCphcmd2KTsKCglzZXR1dGVudCgpOwoKCWlvdi5pb3ZfYmFzZSA9IG1idWY7Cglpb3YuaW92X2xlbiA9IG1idWZzaXplOwoJd2hpbGUoKHV0bXBwdHIgPSBnZXR1dGVudCgpKSkgewoJCWlmICghdXRtcHB0ci0+dXRfbmFtZVswXSB8fAoJCSAgICAhc3RybmNtcCh1dG1wcHRyLT51dF9uYW1lLCBJR05PUkVVU0VSLAoJCQkgICAgIHNpemVvZih1dG1wcHRyLT51dF9uYW1lKSkpCgkJCWNvbnRpbnVlOwojaWZkZWYgVVNFUl9QUk9DRVNTCgkJaWYgKHV0bXBwdHItPnV0X3R5cGUgIT0gVVNFUl9QUk9DRVNTKQoJCQljb250aW51ZTsKI2VuZGlmCgoJCS8qIEpvZXkgSGVzcyByZXBvcnRzIHRoYXQgdXNlLXNlc3NyZWcgaW4gL2V0Yy9YMTEvd2RtLwoJCSAgIHByb2R1Y2VzIHV0X2xpbmUgZW50cmllcyBsaWtlIDowLCBhbmQgYSB3cml0ZQoJCSAgIHRvIC9kZXYvOjAgZmFpbHMuICovCgkJaWYgKHV0bXBwdHItPnV0X2xpbmVbMF0gPT0gJzonKQoJCQljb250aW51ZTsKCgkJeHN0cm5jcHkobGluZSwgdXRtcHB0ci0+dXRfbGluZSwgc2l6ZW9mKHV0bXBwdHItPnV0X2xpbmUpKTsKCQlpZiAoKHAgPSB0dHltc2coJmlvdiwgMSwgbGluZSwgNjAqNSkpICE9IE5VTEwpCgkJCSh2b2lkKWZwcmludGYoc3RkZXJyLCAiJXM6ICVzXG4iLCBwcm9nbmFtZSwgcCk7Cgl9CgllbmR1dGVudCgpOwoJZXhpdCgwKTsKfQoKdm9pZAptYWtlbXNnKGZuYW1lKQoJY2hhciAqZm5hbWU7CnsKCXJlZ2lzdGVyIGludCBjaCwgY250OwoJc3RydWN0IHRtICpsdDsKCXN0cnVjdCBwYXNzd2QgKnB3OwoJc3RydWN0IHN0YXQgc2J1ZjsKCXRpbWVfdCBub3c7CglGSUxFICpmcDsKCWludCBmZDsKCWNoYXIgKnAsICp3aG9tLCAqd2hlcmUsIGhvc3RuYW1lW01BWEhPU1ROQU1FTEVOXSwKCQlsYnVmW01BWEhPU1ROQU1FTEVOICsgMzIwXSwKCQl0bXBuYW1lW3NpemVvZihfUEFUSF9UTVApICsgMjBdOwoKCSh2b2lkKXNwcmludGYodG1wbmFtZSwgIiVzL3dhbGwuWFhYWFhYIiwgX1BBVEhfVE1QKTsKCWlmICghKGZkID0gbWtzdGVtcCh0bXBuYW1lKSkgfHwgIShmcCA9IGZkb3BlbihmZCwgInIrIikpKSB7CgkJKHZvaWQpZnByaW50ZihzdGRlcnIsIF8oIiVzOiBjYW4ndCBvcGVuIHRlbXBvcmFyeSBmaWxlLlxuIiksIHByb2duYW1lKTsKCQlleGl0KDEpOwoJfQoJKHZvaWQpdW5saW5rKHRtcG5hbWUpOwoKCWlmICghbm9iYW5uZXIpIHsKCQlpZiAoISh3aG9tID0gZ2V0bG9naW4oKSkgfHwgISp3aG9tKQoJCQl3aG9tID0gKHB3ID0gZ2V0cHd1aWQoZ2V0dWlkKCkpKSA/IHB3LT5wd19uYW1lIDogIj8/PyI7CgkJaWYgKCF3aG9tIHx8IHN0cmxlbih3aG9tKSA+IDEwMCkKCQkJd2hvbSA9ICJzb21lb25lIjsKCQl3aGVyZSA9IHR0eW5hbWUoMik7CgkJaWYgKCF3aGVyZSB8fCBzdHJsZW4od2hlcmUpID4gMTAwKQoJCQl3aGVyZSA9ICJzb21ld2hlcmUiOwoJCSh2b2lkKWdldGhvc3RuYW1lKGhvc3RuYW1lLCBzaXplb2YoaG9zdG5hbWUpKTsKCQkodm9pZCl0aW1lKCZub3cpOwoJCWx0ID0gbG9jYWx0aW1lKCZub3cpOwoKCQkvKgoJCSAqIGFsbCB0aGlzIHN0dWZmIGlzIHRvIGJsYW5rIG91dCBhIHNxdWFyZSBmb3IgdGhlIG1lc3NhZ2U7CgkJICogd2Ugd3JhcCBtZXNzYWdlIGxpbmVzIGF0IGNvbHVtbiA3OSwgbm90IDgwLCBiZWNhdXNlIHNvbWUKCQkgKiB0ZXJtaW5hbHMgd3JhcCBhZnRlciA3OSwgc29tZSBkbyBub3QsIGFuZCB3ZSBjYW4ndCB0ZWxsLgoJCSAqIFdoaWNoIG1lYW5zIHRoYXQgd2UgbWF5IGxlYXZlIGEgbm9uLWJsYW5rIGNoYXJhY3RlcgoJCSAqIGluIGNvbHVtbiA4MCwgYnV0IHRoYXQgY2FuJ3QgYmUgaGVscGVkLgoJCSAqLwoJCS8qIHNucHJpbnRmIGlzIG5vdCBhbHdheXMgYXZhaWxhYmxlLCBidXQgdGhlIHNwcmludGYncyBoZXJlCgkJICAgd2lsbCBub3Qgb3ZlcmZsb3cgYXMgbG9uZyBhcyAlZCB0YWtlcyBhdCBtb3N0IDEwMCBjaGFycyAqLwoJCSh2b2lkKWZwcmludGYoZnAsICJcciU3OXNcclxuIiwgIiAiKTsKCQkodm9pZClzcHJpbnRmKGxidWYsIF8oIkJyb2FkY2FzdCBNZXNzYWdlIGZyb20gJXNAJXMiKSwKCQkJICAgICAgd2hvbSwgaG9zdG5hbWUpOwoJCSh2b2lkKWZwcmludGYoZnAsICIlLTc5Ljc5c1wwMDdcMDA3XHJcbiIsIGxidWYpOwoJCSh2b2lkKXNwcmludGYobGJ1ZiwgIiAgICAgICAgKCVzKSBhdCAlZDolMDJkIC4uLiIsCgkJCSAgICAgIHdoZXJlLCBsdC0+dG1faG91ciwgbHQtPnRtX21pbik7CgkJKHZvaWQpZnByaW50ZihmcCwgIiUtNzkuNzlzXHJcbiIsIGxidWYpOwoJfQoJKHZvaWQpZnByaW50ZihmcCwgIiU3OXNcclxuIiwgIiAiKTsKCglpZiAoZm5hbWUpIHsKCQkvKgoJCSAqIFdoZW4gd2UgYXJlIG5vdCByb290LCBidXQgc3VpZCBvciBzZ2lkLCByZWZ1c2UgdG8gcmVhZCBmaWxlcwoJCSAqIChlLmcuIGRldmljZSBmaWxlcykgdGhhdCB0aGUgdXNlciBtYXkgbm90IGhhdmUgYWNjZXNzIHRvLgoJCSAqIEFmdGVyIGFsbCwgb3VyIGludm9rZXIgY2FuIGVhc2lseSBkbyAid2FsbCA8IGZpbGUiCgkJICogaW5zdGVhZCBvZiAid2FsbCBmaWxlIi4KCQkgKi8KCQlpbnQgdWlkID0gZ2V0dWlkKCk7CgkJaWYgKHVpZCAmJiAodWlkICE9IGdldGV1aWQoKSB8fCBnZXRnaWQoKSAhPSBnZXRlZ2lkKCkpKSB7CgkJCWZwcmludGYoc3RkZXJyLCBfKCIlczogd2lsbCBub3QgcmVhZCAlcyAtIHVzZSBzdGRpbi5cbiIpLAoJCQkJcHJvZ25hbWUsIGZuYW1lKTsKCQkJZXhpdCgxKTsKCQl9CgkJaWYgKCFmcmVvcGVuKGZuYW1lLCAiciIsIHN0ZGluKSkgewoJCQlmcHJpbnRmKHN0ZGVyciwgXygiJXM6IGNhbid0IHJlYWQgJXMuXG4iKSwKCQkJCXByb2duYW1lLCBmbmFtZSk7CgkJCWV4aXQoMSk7CgkJfQoJfQoKCXdoaWxlIChmZ2V0cyhsYnVmLCBzaXplb2YobGJ1ZiksIHN0ZGluKSkgewoJCWZvciAoY250ID0gMCwgcCA9IGxidWY7IChjaCA9ICpwKSAhPSAnXDAnOyArK3AsICsrY250KSB7CgkJCWlmIChjbnQgPT0gNzkgfHwgY2ggPT0gJ1xuJykgewoJCQkJZm9yICg7IGNudCA8IDc5OyArK2NudCkKCQkJCQlwdXRjKCcgJywgZnApOwoJCQkJcHV0YygnXHInLCBmcCk7CgkJCQlwdXRjKCdcbicsIGZwKTsKCQkJCWNudCA9IDA7CgkJCX0KCQkJaWYgKGNoICE9ICdcbicpCgkJCQljYXJlZnVscHV0YyhjaCwgZnApOwoJCX0KCX0KCWZwcmludGYoZnAsICIlNzlzXHJcbiIsICIgIik7CglyZXdpbmQoZnApOwoKCWlmIChmc3RhdChmZCwgJnNidWYpKSB7CgkJZnByaW50ZihzdGRlcnIsIF8oIiVzOiBjYW4ndCBzdGF0IHRlbXBvcmFyeSBmaWxlLlxuIiksCgkJCXByb2duYW1lKTsKCQlleGl0KDEpOwoJfQoJbWJ1ZnNpemUgPSBzYnVmLnN0X3NpemU7CglpZiAoIShtYnVmID0gbWFsbG9jKCh1X2ludCltYnVmc2l6ZSkpKSB7CgkJKHZvaWQpZnByaW50ZihzdGRlcnIsIF8oIiVzOiBPdXQgb2YgbWVtb3J5IVxuIiksIHByb2duYW1lKTsKCQlleGl0KDEpOwoJfQoJaWYgKGZyZWFkKG1idWYsIHNpemVvZigqbWJ1ZiksIG1idWZzaXplLCBmcCkgIT0gbWJ1ZnNpemUpIHsKCQkodm9pZClmcHJpbnRmKHN0ZGVyciwgXygiJXM6IGNhbid0IHJlYWQgdGVtcG9yYXJ5IGZpbGUuXG4iKSwgcHJvZ25hbWUpOwoJCWV4aXQoMSk7Cgl9Cgkodm9pZCljbG9zZShmZCk7Cn0K