LyoKICAgIHBhcnRlZCAtIGEgZnJvbnRlbmQgdG8gbGlicGFydGVkCiAgICBDb3B5cmlnaHQgKEMpIDE5OTksIDIwMDAsIDIwMDEgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCgogICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICAgIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAgICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogICAgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KCiAgICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAgICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAgICBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAgICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogICAgRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQoqLwoKI2luY2x1ZGUgPGNvbmZpZy5oPgoKI2luY2x1ZGUgPHBhcnRlZC9kZWJ1Zy5oPgoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGxpbWl0cy5oPgoKI2lmZGVmIEVOQUJMRV9OTFMKCiN1bmRlZiBfX1VTRV9HTlUKI2RlZmluZSBfX1VTRV9HTlUKCiNpbmNsdWRlIDx3Y2hhci5oPgojaW5jbHVkZSA8d2N0eXBlLmg+CgojZWxzZSAvKiBFTkFCTEVfTkxTICovCgojaWZkZWYgd2NoYXJfdAojdW5kZWYgd2NoYXJfdAojZW5kaWYKCiNkZWZpbmUgd2NoYXJfdCBjaGFyCgojZW5kaWYgLyogIUVOQUJMRV9OTFMgKi8KCiNpbmNsdWRlICJzdHJsaXN0LmgiCgojZGVmaW5lIE1JTihhLGIpCSggKGE8Yik/ICBhIDogYiApCgppbnQKd2NoYXJfc3RybGVuIChjb25zdCB3Y2hhcl90KiBzdHIpCnsKI2lmZGVmIEVOQUJMRV9OTFMKCXJldHVybiB3Y3NsZW4gKHN0cik7CiNlbHNlCglyZXR1cm4gc3RybGVuIChzdHIpOwojZW5kaWYKfQoKd2NoYXJfdCoKd2NoYXJfc3RyY2hyIChjb25zdCB3Y2hhcl90KiBzdHIsIGNoYXIgY2gpCnsKI2lmZGVmIEVOQUJMRV9OTFMKCXJldHVybiB3Y3NjaHIgKHN0ciwgY2gpOwojZWxzZQoJcmV0dXJuIHN0cmNociAoc3RyLCBjaCk7CiNlbmRpZgp9CgppbnQKd2NoYXJfc3RyY2FzZWNtcCAoY29uc3Qgd2NoYXJfdCogYSwgY29uc3Qgd2NoYXJfdCogYikKewojaWZkZWYgRU5BQkxFX05MUwoJcmV0dXJuIHdjc2Nhc2VjbXAgKGEsIGIpOwojZWxzZQoJcmV0dXJuIHN0cmNhc2VjbXAgKGEsIGIpOwojZW5kaWYKfQoKaW50CndjaGFyX3N0cm5jYXNlY21wIChjb25zdCB3Y2hhcl90KiBhLCBjb25zdCB3Y2hhcl90KiBiLCBzaXplX3QgbikKewojaWZkZWYgRU5BQkxFX05MUwoJcmV0dXJuIHdjc25jYXNlY21wIChhLCBiLCBuKTsKI2Vsc2UKCXJldHVybiBzdHJuY2FzZWNtcCAoYSwgYiwgbik7CiNlbmRpZgp9Cgp3Y2hhcl90Kgp3Y2hhcl9zdHJkdXAgKGNvbnN0IHdjaGFyX3QqIHN0cikKewojaWZkZWYgRU5BQkxFX05MUwoJcmV0dXJuIHdjc2R1cCAoc3RyKTsKI2Vsc2UKCXJldHVybiBzdHJkdXAgKHN0cik7CiNlbmRpZgp9CgovKiBjb252ZXJ0cyBhIHN0cmluZyBmcm9tIHRoZSBlbmNvZGluZyBpbiB0aGUgZ2V0dGV4dCBjYXRhbG9ndWVzIHRvIHdpZGUKICogY2hhcmFjdGVyIHN0cmluZ3MgKG9mIHR5cGUgd2NoYXJfdCopLgogKi8KI2lmZGVmIEVOQUJMRV9OTFMKc3RhdGljIHdjaGFyX3QqCmdldHRleHRfdG9fd2NoYXIgKGNvbnN0IGNoYXIqIHN0cikKewoJaW50CQljb3VudDsKCXdjaGFyX3QqCXJlc3VsdDsKCXNpemVfdAkJc3RhdHVzOwoJbWJzdGF0ZV90CXBzOwoKCWNvdW50ID0gc3RybGVuIChzdHIpICsgMTsKCXJlc3VsdCA9IG1hbGxvYyAoY291bnQgKiBzaXplb2YgKHdjaGFyX3QpKTsKCWlmICghcmVzdWx0KQoJCWdvdG8gZXJyb3I7CgoJbWVtc2V0KCZwcywgMCwgc2l6ZW9mIChwcykpOwoJc3RhdHVzID0gbWJzcnRvd2NzKHJlc3VsdCwgJnN0ciwgY291bnQsICZwcyk7CglpZiAoc3RhdHVzID09IChzaXplX3QpIC0xKQoJCWdvdG8gZXJyb3I7CgoJcmVzdWx0ID0gcmVhbGxvYyAocmVzdWx0LCAod2NzbGVuIChyZXN1bHQpICsgMSkgKiBzaXplb2YgKHdjaGFyX3QpKTsKCXJldHVybiByZXN1bHQ7CgplcnJvcjoKCXByaW50ZiAoIkVycm9yIGR1cmluZyB0cmFuc2xhdGlvbjogJXNcbiIsIHN0cmVycm9yIChlcnJubykpOwoJZXhpdCAoMSk7Cn0KCiNlbHNlIC8qIEVOQUJMRV9OTFMgKi8KCnN0YXRpYyB3Y2hhcl90KgpnZXR0ZXh0X3RvX3djaGFyIChjb25zdCBjaGFyKiBzdHIpCnsKCXJldHVybiBzdHJkdXAgKHN0cik7Cn0KCiNlbmRpZiAvKiAhRU5BQkxFX05MUyAqLwoKCiNpZmRlZiBFTkFCTEVfTkxTCnN0YXRpYyBjaGFyKgp3Y2hhcl90b19zdHIgKGNvbnN0IHdjaGFyX3QqIHN0ciwgc2l6ZV90IGNvdW50KQp7CgljaGFyKgkJcmVzdWx0OwoJY2hhcioJCW91dF9idWY7CglzaXplX3QJCXN0YXR1czsKCW1ic3RhdGVfdAlwczsKCXNpemVfdAkJaTsKCglpZiAoY291bnQgPT0gMCB8fCB3Y3NsZW4oc3RyKSA8IGNvdW50KQoJCWNvdW50ID0gd2NzbGVuIChzdHIpOwoKCW91dF9idWYgPSByZXN1bHQgPSBtYWxsb2MgKChjb3VudCArIDEpICogIE1CX0xFTl9NQVgpOwoJaWYgKCFyZXN1bHQpCgkJZ290byBlcnJvcjsKCgltZW1zZXQoJnBzLCAwLCBzaXplb2YocHMpKTsKCglmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCXN0YXR1cyA9IHdjcnRvbWIgKG91dF9idWYsIHN0cltpXSwgJnBzKTsKCQlpZiAoc3RhdHVzID09IChzaXplX3QpIC0xKQoJCQlnb3RvIGVycm9yOwoJCW91dF9idWYgKz0gc3RhdHVzOwoJfQoKCXN0YXR1cyA9IHdjcnRvbWIgKG91dF9idWYsIDAsICZwcyk7CglpZiAoc3RhdHVzID09IChzaXplX3QpIC0xKQoJCWdvdG8gZXJyb3I7CgoJcmVzdWx0ID0gcmVhbGxvYyAocmVzdWx0LCBzdHJsZW4gKHJlc3VsdCkgKyAxKTsKCXJldHVybiByZXN1bHQ7CgplcnJvcjoKCXByaW50ZiAoIkVycm9yIGR1cmluZyB0cmFuc2xhdGlvbjogJXNcbiIsIHN0cmVycm9yIChlcnJubykpOwoJZXhpdCAoMSk7Cn0KCiNlbHNlIC8qIEVOQUJMRV9OTFMgKi8KCnN0YXRpYyBjaGFyKgp3Y2hhcl90b19zdHIgKGNvbnN0IHdjaGFyX3QqIHN0ciwgc2l6ZV90IGNvdW50KQp7CgljaGFyKgkJcmVzdWx0OwoKCXJlc3VsdCA9IHN0cmR1cCAoc3RyKTsKCWlmIChjb3VudCAmJiBjb3VudCA8IHN0cmxlbiAocmVzdWx0KSkKCQlyZXN1bHQgW2NvdW50XSA9IDA7CglyZXR1cm4gcmVzdWx0Owp9CgojZW5kaWYgLyogIUVOQUJMRV9OTFMgKi8KCnN0YXRpYyB2b2lkCnByaW50X3djaGFyIChjb25zdCB3Y2hhcl90KiBzdHIsIHNpemVfdCBjb3VudCkKewoJY2hhcioJdG1wID0gd2NoYXJfdG9fc3RyIChzdHIsIGNvdW50KTsKCXByaW50ZiAoIiVzIiwgdG1wKTsKCWZyZWUgKHRtcCk7Cn0KCnN0YXRpYyBTdHJMaXN0KiAKc3RyX2xpc3RfYWxsb2MgKCkKewoJU3RyTGlzdCoJbGlzdDsKCglsaXN0ID0gKFN0ckxpc3QqKSBtYWxsb2MgKHNpemVvZiAoU3RyTGlzdCkpOwoJbGlzdC0+bmV4dCA9IE5VTEw7CgoJcmV0dXJuIGxpc3Q7Cn0KCnZvaWQKc3RyX2xpc3RfZGVzdHJveSAoU3RyTGlzdCogbGlzdCkKewoJaWYgKGxpc3QpIHsKCQlzdHJfbGlzdF9kZXN0cm95IChsaXN0LT5uZXh0KTsKCQlzdHJfbGlzdF9kZXN0cm95X25vZGUgKGxpc3QpOwoJfQp9Cgp2b2lkCnN0cl9saXN0X2Rlc3Ryb3lfbm9kZSAoU3RyTGlzdCogbGlzdCkKewoJZnJlZSAoKHdjaGFyX3QqKSBsaXN0LT5zdHIpOwoJZnJlZSAobGlzdCk7Cn0KClN0ckxpc3QqCnN0cl9saXN0X2R1cGxpY2F0ZV9ub2RlIChjb25zdCBTdHJMaXN0KiBub2RlKQp7CglTdHJMaXN0KglyZXN1bHQgPSBzdHJfbGlzdF9hbGxvYyAoKTsKCXJlc3VsdC0+c3RyID0gd2NoYXJfc3RyZHVwIChub2RlLT5zdHIpOwoJcmV0dXJuIHJlc3VsdDsKfQoKU3RyTGlzdCoKc3RyX2xpc3RfZHVwbGljYXRlIChjb25zdCBTdHJMaXN0KiBsaXN0KQp7CglpZiAobGlzdCkKCQlyZXR1cm4gc3RyX2xpc3Rfam9pbiAoc3RyX2xpc3RfZHVwbGljYXRlX25vZGUgKGxpc3QpLAoJCQkJICAgICAgc3RyX2xpc3RfZHVwbGljYXRlIChsaXN0LT5uZXh0KSk7CgllbHNlCgkJcmV0dXJuIE5VTEw7Cn0KClN0ckxpc3QqCnN0cl9saXN0X2pvaW4gKFN0ckxpc3QqIGEsIFN0ckxpc3QqIGIpCnsKCVN0ckxpc3QqCXdhbGs7CgoJZm9yICh3YWxrID0gYTsgd2FsayAmJiB3YWxrLT5uZXh0OyB3YWxrID0gd2Fsay0+bmV4dCk7CgoJaWYgKHdhbGspIHsKCQl3YWxrLT5uZXh0ID0gYjsKCQlyZXR1cm4gYTsKCX0gZWxzZSB7CgkJcmV0dXJuIGI7Cgl9Cn0KCnN0YXRpYyBTdHJMaXN0Kgpfc3RyX2xpc3RfYXBwZW5kIChTdHJMaXN0KiBsaXN0LCBjb25zdCB3Y2hhcl90KiBzdHIpCnsKCVN0ckxpc3QqCXdhbGs7CgoJaWYgKGxpc3QpIHsKCQlmb3IgKHdhbGsgPSBsaXN0OyB3YWxrLT5uZXh0OyB3YWxrID0gd2Fsay0+bmV4dCk7CgkJd2Fsay0+bmV4dCA9IHN0cl9saXN0X2FsbG9jICgpOwoJCXdhbGsgPSB3YWxrLT5uZXh0OwoJfSBlbHNlIHsKCQl3YWxrID0gbGlzdCA9IHN0cl9saXN0X2FsbG9jICgpOwoJfQoJd2Fsay0+c3RyID0gc3RyOwoKCXJldHVybiBsaXN0Owp9CgpTdHJMaXN0KgpzdHJfbGlzdF9hcHBlbmQgKFN0ckxpc3QqIGxpc3QsIGNvbnN0IGNoYXIqIHN0cikKewoJcmV0dXJuIF9zdHJfbGlzdF9hcHBlbmQgKGxpc3QsIGdldHRleHRfdG9fd2NoYXIgKHN0cikpOwp9CgpTdHJMaXN0KgpzdHJfbGlzdF9hcHBlbmRfdW5pcXVlIChTdHJMaXN0KiBsaXN0LCBjb25zdCBjaGFyKiBzdHIpCnsKCVN0ckxpc3QqCXdhbGs7Cgl3Y2hhcl90KgluZXdfc3RyID0gZ2V0dGV4dF90b193Y2hhciAoc3RyKTsKCglmb3IgKHdhbGs9bGlzdDsgd2Fsazsgd2Fsaz13YWxrLT5uZXh0KSB7CgkJaWYgKHdhbGstPnN0cikgewoJCQlpZiAod2NoYXJfc3RyY2FzZWNtcCAobmV3X3N0ciwgd2Fsay0+c3RyKSA9PSAwKSB7CgkJCQlmcmVlIChuZXdfc3RyKTsKCQkJCXJldHVybiBsaXN0OwoJCQl9CgkJfQoJfQoKCXJldHVybiBfc3RyX2xpc3RfYXBwZW5kIChsaXN0LCBuZXdfc3RyKTsKfQoKU3RyTGlzdCoKc3RyX2xpc3RfaW5zZXJ0IChTdHJMaXN0KiBsaXN0LCBjb25zdCBjaGFyKiBzdHIpCnsKCXJldHVybiBzdHJfbGlzdF9qb2luIChzdHJfbGlzdF9jcmVhdGUgKHN0ciwgTlVMTCksIGxpc3QpOwp9CgpTdHJMaXN0KgpzdHJfbGlzdF9jcmVhdGUgKGNvbnN0IGNoYXIqIGZpcnN0LCAuLi4pCnsKCXZhX2xpc3QJCWFyZ3M7CgljaGFyKgkJc3RyOwoJU3RyTGlzdCoJbGlzdDsKCglsaXN0ID0gc3RyX2xpc3RfYXBwZW5kIChOVUxMLCBmaXJzdCk7CgoJaWYgKGZpcnN0KSB7CgkJdmFfc3RhcnQgKGFyZ3MsIGZpcnN0KTsKCQl3aGlsZSAoIChzdHIgPSB2YV9hcmcgKGFyZ3MsIGNoYXIqKSkgKQoJCQlzdHJfbGlzdF9hcHBlbmQgKGxpc3QsIHN0cik7CgkJdmFfZW5kIChhcmdzKTsKCX0KCglyZXR1cm4gbGlzdDsKfQoKU3RyTGlzdCoKc3RyX2xpc3RfY3JlYXRlX3VuaXF1ZSAoY29uc3QgY2hhciogZmlyc3QsIC4uLikKewoJdmFfbGlzdAkJYXJnczsKCWNoYXIqCQlzdHI7CglTdHJMaXN0KglsaXN0OwoKCWxpc3QgPSBzdHJfbGlzdF9hcHBlbmQgKE5VTEwsIGZpcnN0KTsKCglpZiAoZmlyc3QpIHsKCQl2YV9zdGFydCAoYXJncywgZmlyc3QpOwoJCXdoaWxlICggKHN0ciA9IHZhX2FyZyAoYXJncywgY2hhciopKSApCgkJCXN0cl9saXN0X2FwcGVuZF91bmlxdWUgKGxpc3QsIHN0cik7CgkJdmFfZW5kIChhcmdzKTsKCX0KCglyZXR1cm4gbGlzdDsKfQoKY2hhcioKc3RyX2xpc3RfY29udmVydF9ub2RlIChjb25zdCBTdHJMaXN0KiBsaXN0KQp7CglyZXR1cm4gd2NoYXJfdG9fc3RyIChsaXN0LT5zdHIsIDApOwp9CgpjaGFyKgpzdHJfbGlzdF9jb252ZXJ0IChjb25zdCBTdHJMaXN0KiBsaXN0KQp7Cgljb25zdCBTdHJMaXN0Kgl3YWxrOwoJaW50CQlwb3MgPSAwOwoJaW50CQlsZW5ndGggPSAxOwoJY2hhcioJCXN0ciA9IHN0cmR1cCAoIiIpOwoKCWZvciAod2FsayA9IGxpc3Q7IHdhbGs7IHdhbGsgPSB3YWxrLT5uZXh0KSB7CgkJaWYgKHdhbGstPnN0cikgewoJCQljaGFyKgl0bXAgPSB3Y2hhcl90b19zdHIgKHdhbGstPnN0ciwgMCk7CgoJCQlsZW5ndGggKz0gc3RybGVuICh0bXApOwoKCQkJc3RyID0gcmVhbGxvYyAoc3RyLCBsZW5ndGgpOwoJCQlzdHJjcHkgKHN0ciArIHBvcywgdG1wKTsKCgkJCXBvcyA9IGxlbmd0aCAtIDE7CgkJCWZyZWUgKHRtcCk7CgkJfQoJfQoKCXJldHVybiBzdHI7Cn0KCnZvaWQKc3RyX2xpc3RfcHJpbnQgKGNvbnN0IFN0ckxpc3QqIGxpc3QpCnsKCWNvbnN0IFN0ckxpc3QqCXdhbGs7CgoJZm9yICh3YWxrPWxpc3Q7IHdhbGs7IHdhbGs9d2Fsay0+bmV4dCkgewoJCWlmICh3YWxrLT5zdHIpCgkJCXByaW50X3djaGFyICh3YWxrLT5zdHIsIDApOwoJfQp9CgpzdGF0aWMgY2hhcioKZ2V0X3NwYWNlcyAoaW50IHNwYWNlX2NvdW50KQp7CgljaGFyKglzdHI7CglpbnQJaTsKCglzdHIgPSBtYWxsb2MgKHNwYWNlX2NvdW50ICsgMSk7Cglmb3IgKGkgPSAwOyBpIDwgc3BhY2VfY291bnQ7IGkrKykKCQlzdHIgW2ldID0gJyAnOwoJc3RyIFtpXSA9IDA7CgoJcmV0dXJuIHN0cjsKfQoKc3RhdGljIGludApzdHJfc2VhcmNoIChjb25zdCB3Y2hhcl90KiBzdHIsIGludCBuLCB3Y2hhcl90IGMpCnsKCWludAlpOwoKCWZvciAoaT0wOyBpPG47IGkrKykKCQlpZiAoc3RyIFtpXSA9PSBjKQoJCQlyZXR1cm4gaTsKCXJldHVybiAtMTsKfQoKCi8qIEphcGFuZXNlIGRvbid0IGxlYXZlIHNwYWNlcyBiZXR3ZWVuIHdvcmRzLCBzbyBBTEwgSmFwYW5lc2UgY2hhcmFjdGVycwogKiBhcmUgdHJlYXRlZCBhcyBkZWxpbWl0ZXJzLiAgTm90ZTogc2luY2UgdGhlIHRyYW5zbGF0aW9ucyBzaG91bGQgYWxyZWFkeQogKiBiZSBwcm9wZXJseSBmb3JtYXR0ZWQgKGVnOiBzcGFjZXMgYWZ0ZXIgY29tbWFzKSwgdGhlcmUgc2hvdWxkIGJlIG5vCiAqIG5lZWQgdG8gaW5jbHVkZSB0aGVtLiAgQmVzdCBub3QgdG8gYXZvaWQgc2lkZSBlZmZlY3RzLCBsaWtlIDMuCjE0MTU5IDotKQogKiBGSVhNRTogaG93IGRvIHdlIGV4Y2x1ZGUgIi4iIGFuZCAiKCIgPwogKiBGSVhNRTogZ2xpYmMgZG9lc24ndCBsaWtlIHVtbGF1dGUuICBpLmUuIFwibyAoVGVYIG5vdGF0aW9uKSwgd2hpY2ggc2hvdWxkCiAqIGxvb2sgbGlrZTog9gogKi8KCnN0YXRpYyBpbnQKaXNfYnJlYWtfcG9pbnQgKHdjaGFyX3QgYykKewojaWZkZWYgRU5BQkxFX05MUwoJcmV0dXJuICFpc3dhbG51bSAoYykgJiYgIWlzd3B1bmN0IChjKTsKI2Vsc2UKCXJldHVybiAhaXNhbG51bSAoYykgJiYgIWlzcHVuY3QgKGMpOwojZW5kaWYKfQoKLyogTk9URTogdGhpcyBzaG91bGQgbm90IHJldHVybiAnXG4nIGFzIGEgc3BhY2UsIGJlY2F1c2UgZXhwbGljaXQgJ1xuJyBtYXkKICogYmUgcGxhY2VkIGluc2lkZSBzdHJpbmdzLgogKi8Kc3RhdGljIGludAppc19zcGFjZSAod2NoYXJfdCBjKQp7CiNpZmRlZiBFTkFCTEVfTkxTCglyZXR1cm4gYyA9PSAod2NoYXJfdCkgYnRvd2MoJyAnKTsKI2Vsc2UKCXJldHVybiBjID09ICcgJzsKI2VuZGlmCn0KCnZvaWQKc3RyX2xpc3RfcHJpbnRfd3JhcCAoY29uc3QgU3RyTGlzdCogbGlzdCwgaW50IGxpbmVfbGVuZ3RoLCBpbnQgb2Zmc2V0LAoJCSAgICAgaW50IGluZGVudCkKewoJY29uc3QgU3RyTGlzdCoJd2FsazsKCWNvbnN0IHdjaGFyX3QqCXN0cjsKCWludAkJc3RyX2xlbjsKCWludAkJY3V0X3JpZ2h0OwoJaW50CQljdXRfbGVmdDsKCWludAkJbGluZV9sZWZ0OwoJY2hhcioJCXNwYWNlczsKCWludAkJc2VhcmNoX3Jlc3VsdDsKCWludAkJbGluZV9icmVhazsKCglQRURfQVNTRVJUIChsaW5lX2xlbmd0aCAtIGluZGVudCA+IDEwLCByZXR1cm4pOwoKCXNwYWNlcyA9IGdldF9zcGFjZXMgKGluZGVudCk7CglsaW5lX2xlZnQgPSBsaW5lX2xlbmd0aCAtIG9mZnNldDsKCglmb3IgKHdhbGs9bGlzdDsgd2Fsazsgd2Fsaz13YWxrLT5uZXh0KSB7CgkJaWYgKCF3YWxrLT5zdHIpCgkJCWNvbnRpbnVlOwoJCXN0ciA9IHdhbGstPnN0cjsKCQlzdHJfbGVuID0gd2NoYXJfc3RybGVuIChzdHIpOwoKCQl3aGlsZSAobGluZV9sZWZ0IDwgc3RyX2xlbiB8fCB3Y2hhcl9zdHJjaHIgKHN0ciwgJ1xuJykpIHsKCQkJbGluZV9icmVhayA9IDA7CgoJCQljdXRfbGVmdCA9IE1JTiAobGluZV9sZWZ0IC0gMSwgc3RyX2xlbiAtIDEpOwoKCQkJLyogd2UgY2FuIGhhdmUgYSBzcGFjZSAib3ZlciIsIGJ1dCBub3QgYSBjb21tYSAqLwoJCQlpZiAoY3V0X2xlZnQgPCBzdHJfbGVuCgkJCQkJJiYgaXNfc3BhY2UgKHN0ciBbY3V0X2xlZnQgKyAxXSkpCgkJCQljdXRfbGVmdCsrOwoKCQkJd2hpbGUgKGN1dF9sZWZ0ICYmICFpc19icmVha19wb2ludCAoc3RyIFtjdXRfbGVmdF0pKQoJCQkJY3V0X2xlZnQtLTsKCQkJd2hpbGUgKGN1dF9sZWZ0ICYmIGlzX3NwYWNlIChzdHIgW2N1dF9sZWZ0XSkpCgkJCQljdXRfbGVmdC0tOwoKCQkvKiBzdHIgW2N1dF9sZWZ0XSBpcyBlaXRoZXIgdGhlIGVuZCBvZiBhIHdvcmQsIG9yIGEKCQkgKiBKYXBhbmVzZSBjaGFyYWN0ZXIsIG9yIHRoZSBzdGFydCBvZiBhIGJsYW5rIGxpbmUuCgkJICovCgoJCQlzZWFyY2hfcmVzdWx0ID0gc3RyX3NlYXJjaCAoc3RyLCBjdXRfbGVmdCArIDEsICdcbicpOwoJCQlpZiAoc2VhcmNoX3Jlc3VsdCAhPSAtMSkgewoJCQkJY3V0X2xlZnQgPSBzZWFyY2hfcmVzdWx0IC0gMTsKCQkJCWxpbmVfYnJlYWsgPSAxOwoJCQl9CgoJCQlmb3IgKGN1dF9yaWdodCA9IGN1dF9sZWZ0ICsgKGxpbmVfYnJlYWsgPyAyIDogMSk7CgkJCSAgICAgY3V0X3JpZ2h0IDwgc3RyX2xlbiAmJiBpc19zcGFjZSAoc3RyIFtjdXRfcmlnaHRdKTsKCQkJICAgICBjdXRfcmlnaHQrKyk7CgoJCQlpZiAoY3V0X2xlZnQgPiAwKQoJCQkJcHJpbnRfd2NoYXIgKHN0ciwgY3V0X2xlZnQgKyAxKTsKCgkJCXN0ciArPSBjdXRfcmlnaHQ7CgkJCXN0cl9sZW4gLT0gY3V0X3JpZ2h0OwoJCQlsaW5lX2xlZnQgPSBsaW5lX2xlbmd0aCAtIGluZGVudDsKCgkJCWlmICh3YWxrLT5uZXh0IHx8ICpzdHIpCgkJCQlwcmludGYgKCJcbiVzIiwgc3BhY2VzKTsKCQkJZWxzZSBpZiAobGluZV9icmVhaykKCQkJCXB1dGNoYXIgKCdcbicpOwoJCX0KCgkJcHJpbnRfd2NoYXIgKHN0ciwgMCk7CgkJbGluZV9sZWZ0IC09IHdjaGFyX3N0cmxlbiAoc3RyKTsKCX0KCglmcmVlIChzcGFjZXMpOwp9CgpzdGF0aWMgaW50Cl9zdHJfbGlzdF9tYXRjaF9ub2RlIChjb25zdCBTdHJMaXN0KiBsaXN0LCBjb25zdCB3Y2hhcl90KiBzdHIpCnsKCWlmICh3Y2hhcl9zdHJjYXNlY21wIChsaXN0LT5zdHIsIHN0cikgPT0gMCkKCQlyZXR1cm4gMjsKCWlmICh3Y2hhcl9zdHJuY2FzZWNtcCAobGlzdC0+c3RyLCBzdHIsIHdjaGFyX3N0cmxlbiAoc3RyKSkgPT0gMCkKCQlyZXR1cm4gMTsKCXJldHVybiAwOwp9CgppbnQKc3RyX2xpc3RfbWF0Y2hfbm9kZSAoY29uc3QgU3RyTGlzdCogbGlzdCwgY29uc3QgY2hhciogc3RyKQp7Cgl3Y2hhcl90Kgl3Y19zdHIgPSBnZXR0ZXh0X3RvX3djaGFyIChzdHIpOwkvKiBGSVhNRSAqLwoJaW50CQlzdGF0dXM7CgoJc3RhdHVzID0gX3N0cl9saXN0X21hdGNoX25vZGUgKGxpc3QsIHdjX3N0cik7CglmcmVlICh3Y19zdHIpOwoKCXJldHVybiBzdGF0dXM7Cn0KCi8qIHJldHVybnM6ICAyIGZvciBmdWxsIG1hdGNoCgkgICAgIDEgZm9yIHBhcnRpYWwgbWF0Y2gKCSAgICAgMCBmb3Igbm8gbWF0Y2gKICovCmludApzdHJfbGlzdF9tYXRjaF9hbnkgKGNvbnN0IFN0ckxpc3QqIGxpc3QsIGNvbnN0IGNoYXIqIHN0cikKewoJY29uc3QgU3RyTGlzdCoJd2FsazsKCWludAkJYmVzdF9zdGF0dXMgPSAwOwoJd2NoYXJfdCoJd2Nfc3RyID0gZ2V0dGV4dF90b193Y2hhciAoc3RyKTsKCglmb3IgKHdhbGsgPSBsaXN0OyB3YWxrOyB3YWxrID0gd2Fsay0+bmV4dCkgewoJCWludAl0aGlzX3N0YXR1cyA9IF9zdHJfbGlzdF9tYXRjaF9ub2RlICh3YWxrLCB3Y19zdHIpOwoJCWlmICh0aGlzX3N0YXR1cyA+IGJlc3Rfc3RhdHVzKQoJICAgICAgIAkJYmVzdF9zdGF0dXMgPSB0aGlzX3N0YXR1czsKCX0KCglmcmVlICh3Y19zdHIpOwoJcmV0dXJuIGJlc3Rfc3RhdHVzOwp9CgpTdHJMaXN0KgpzdHJfbGlzdF9tYXRjaCAoY29uc3QgU3RyTGlzdCogbGlzdCwgY29uc3QgY2hhciogc3RyKQp7Cgljb25zdCBTdHJMaXN0Kgl3YWxrOwoJY29uc3QgU3RyTGlzdCoJcGFydGlhbF9tYXRjaCA9IE5VTEw7CglpbnQJCWFtYmlndW91cyA9IDA7Cgl3Y2hhcl90Kgl3Y19zdHIgPSBnZXR0ZXh0X3RvX3djaGFyIChzdHIpOwoKCWZvciAod2FsayA9IGxpc3Q7IHdhbGs7IHdhbGsgPSB3YWxrLT5uZXh0KSB7CgkJc3dpdGNoIChfc3RyX2xpc3RfbWF0Y2hfbm9kZSAod2Fsaywgd2Nfc3RyKSkgewoJCQljYXNlIDI6CgkJCQlmcmVlICh3Y19zdHIpOwoJCQkJcmV0dXJuIChTdHJMaXN0Kikgd2FsazsKCgkJCWNhc2UgMToKCQkJCWlmIChwYXJ0aWFsX21hdGNoKQoJCQkJCWFtYmlndW91cyA9IDE7CgkJCQlwYXJ0aWFsX21hdGNoID0gd2FsazsKCQl9Cgl9CgoJZnJlZSAod2Nfc3RyKTsKCXJldHVybiBhbWJpZ3VvdXMgPyBOVUxMIDogKFN0ckxpc3QqKSBwYXJ0aWFsX21hdGNoOwp9CgppbnQKc3RyX2xpc3RfbGVuZ3RoIChjb25zdCBTdHJMaXN0KiBsaXN0KQp7CglpbnQJCWxlbmd0aCA9IDA7Cgljb25zdCBTdHJMaXN0Kgl3YWxrOwoKCWZvciAod2FsayA9IGxpc3Q7IHdhbGs7IHdhbGsgPSB3YWxrLT5uZXh0KQoJCWxlbmd0aCsrOwoKCXJldHVybiBsZW5ndGg7Cn0KCg==