Ly8gRmlsZTogYmFzaXN1X3dhc21fYXBpLmNwcCAtIFNpbXBsaWZpZWQgY29tcHJlc3Npb24gQVBJIGZvciBXQVNNIFdBU0kgbW9kdWxlcyBhbmQgUHl0aG9uIG5hdGl2ZSBzdXBwb3J0LgovLyBBbHNvIHVzZWFibGUgYnkgcGxhaW4gQyBjYWxsZXJzLgojaW5jbHVkZSAiYmFzaXN1X2NvbXAuaCIKI2luY2x1ZGUgImJhc2lzdV93YXNtX2FwaS5oIgoKdXNpbmcgbmFtZXNwYWNlIGJhc2lzdTsKCnN0YXRpYyBpbmxpbmUgdWludDY0X3Qgd2FzbV9vZmZzZXQodm9pZCogcCkKewogICAgcmV0dXJuICh1aW50NjRfdCkodWludHB0cl90KXA7Cn0KCnN0YXRpYyBpbmxpbmUgdWludDhfdCogd2FzbV9wdHIodWludDY0X3Qgb2Zmc2V0KQp7CglyZXR1cm4gKHVpbnQ4X3QqKSh1aW50cHRyX3Qpb2Zmc2V0Owp9CgpCVV9XQVNNX0VYUE9SVCgiYnVfZ2V0X3ZlcnNpb24iKQp1aW50MzJfdCBidV9nZXRfdmVyc2lvbigpCnsKCXByaW50ZigiSGVsbG8gZnJvbSBiYXNpc3Vfd2FzbV9hcGkuY3BwIHZlcnNpb24gJXVcbiIsIEJBU0lTVV9MSUJfVkVSU0lPTik7CgkJCglyZXR1cm4gQkFTSVNVX0xJQl9WRVJTSU9OOwp9CgpCVV9XQVNNX0VYUE9SVCgiYnVfZW5hYmxlX2RlYnVnX3ByaW50ZiIpCnZvaWQgYnVfZW5hYmxlX2RlYnVnX3ByaW50Zih1aW50MzJfdCBmbGFnKQp7CgllbmFibGVfZGVidWdfcHJpbnRmKGZsYWcgIT0gMCk7Cn0KCkJVX1dBU01fRVhQT1JUKCJidV9pbml0IikKdm9pZCBidV9pbml0KCkKewoJYmFzaXN1X2VuY29kZXJfaW5pdChmYWxzZSwgZmFsc2UpOwp9CgovLyBNZW1vcnkgYWxsb2MvZnJlZSCXIHN0dWJzCkJVX1dBU01fRVhQT1JUKCJidV9hbGxvYyIpCnVpbnQ2NF90IGJ1X2FsbG9jKHVpbnQ2NF90IHNpemUpCnsKICAgIHZvaWQqIHAgPSBtYWxsb2MoKHNpemVfdClzaXplKTsKICAgIHJldHVybiB3YXNtX29mZnNldChwKTsKfQoKQlVfV0FTTV9FWFBPUlQoImJ1X2ZyZWUiKQp2b2lkIGJ1X2ZyZWUodWludDY0X3Qgb2ZzKQp7CiAgICBmcmVlKHdhc21fcHRyKG9mcykpOwp9Cgpjb25zdCB1aW50MzJfdCBDT01QX1BBUkFNU19NQUdJQyA9IDB4NDM1MDRENTA7IC8vICJDUE1QIgoKc3RydWN0IGNvbXBfcGFyYW1zCnsKCXVpbnQzMl90IG1fbWFnaWMgPSBDT01QX1BBUkFNU19NQUdJQzsKCgljb21wX3BhcmFtcygpIAoJewoJCWNsZWFyKCk7Cgl9CgoJdm9pZCBjbGVhcigpCgl7CgkJYXNzZXJ0KG1fbWFnaWMgPT0gQ09NUF9QQVJBTVNfTUFHSUMpOwoKCQltX2NvbXBfZGF0YS5jbGVhcigpOwoJCW1faW1hZ2VzLmNsZWFyKCk7CgkJbV9pbWFnZXNmLmNsZWFyKCk7CgoJCW1fc3RhdHMuY2xlYXIoKTsKCX0KCgl1aW50OF92ZWMgbV9jb21wX2RhdGE7CgoJYmFzaXN1Ojp2ZWN0b3I8aW1hZ2U+IG1faW1hZ2VzOwoJYmFzaXN1Ojp2ZWN0b3I8aW1hZ2VmPiBtX2ltYWdlc2Y7CgoJaW1hZ2Vfc3RhdHMgbV9zdGF0czsKfTsKCkJVX1dBU01fRVhQT1JUKCJidV9uZXdfY29tcF9wYXJhbXMiKQp1aW50NjRfdCBidV9uZXdfY29tcF9wYXJhbXMoKQp7Cgljb21wX3BhcmFtcyogcCA9IG5ldyBjb21wX3BhcmFtczsKCXJldHVybiB3YXNtX29mZnNldChwKTsKfQoKQlVfV0FTTV9FWFBPUlQoImJ1X2RlbGV0ZV9jb21wX3BhcmFtcyIpCndhc21fYm9vbF90IGJ1X2RlbGV0ZV9jb21wX3BhcmFtcyh1aW50NjRfdCBwYXJhbXNfb2ZzKQp7Cgljb21wX3BhcmFtcyogcCA9IChjb21wX3BhcmFtcyopd2FzbV9wdHIocGFyYW1zX29mcyk7CglpZiAoIXApCgkJcmV0dXJuIGZhbHNlOwoKCWFzc2VydChwLT5tX21hZ2ljID09IENPTVBfUEFSQU1TX01BR0lDKTsKCWlmIChwLT5tX21hZ2ljICE9IENPTVBfUEFSQU1TX01BR0lDKQoJCXJldHVybiBmYWxzZTsKCglkZWxldGUgcDsKCglyZXR1cm4gdHJ1ZTsKfQoKQlVfV0FTTV9FWFBPUlQoImJ1X2NvbXBfcGFyYW1zX2dldF9jb21wX2RhdGFfc2l6ZSIpCnVpbnQ2NF90IGJ1X2NvbXBfcGFyYW1zX2dldF9jb21wX2RhdGFfc2l6ZSh1aW50NjRfdCBwYXJhbXNfb2ZzKQp7Cgljb21wX3BhcmFtcyogcFBhcmFtcyA9IChjb21wX3BhcmFtcyopd2FzbV9wdHIocGFyYW1zX29mcyk7CglpZiAoIXBQYXJhbXMpCgkJcmV0dXJuIDA7CgoJYXNzZXJ0KHBQYXJhbXMtPm1fbWFnaWMgPT0gQ09NUF9QQVJBTVNfTUFHSUMpOwoJaWYgKHBQYXJhbXMtPm1fbWFnaWMgIT0gQ09NUF9QQVJBTVNfTUFHSUMpCgkJcmV0dXJuIDA7CgoJcmV0dXJuIHBQYXJhbXMtPm1fY29tcF9kYXRhLnNpemUoKTsKfQoKQlVfV0FTTV9FWFBPUlQoImJ1X2NvbXBfcGFyYW1zX2dldF9jb21wX2RhdGFfb2ZzIikKdWludDY0X3QgYnVfY29tcF9wYXJhbXNfZ2V0X2NvbXBfZGF0YV9vZnModWludDY0X3QgcGFyYW1zX29mcykKewoJY29tcF9wYXJhbXMqIHBQYXJhbXMgPSAoY29tcF9wYXJhbXMqKXdhc21fcHRyKHBhcmFtc19vZnMpOwoJaWYgKCFwUGFyYW1zKQoJCXJldHVybiAwOwoKCWFzc2VydChwUGFyYW1zLT5tX21hZ2ljID09IENPTVBfUEFSQU1TX01BR0lDKTsKCWlmIChwUGFyYW1zLT5tX21hZ2ljICE9IENPTVBfUEFSQU1TX01BR0lDKQoJCXJldHVybiAwOwoKCXJldHVybiB3YXNtX29mZnNldChwUGFyYW1zLT5tX2NvbXBfZGF0YS5nZXRfcHRyKCkpOwp9CgpCVV9XQVNNX0VYUE9SVCgiYnVfY29tcF9wYXJhbXNfY2xlYXIiKQp3YXNtX2Jvb2xfdCBidV9jb21wX3BhcmFtc19jbGVhcih1aW50NjRfdCBwYXJhbXNfb2ZzKQp7Cgljb21wX3BhcmFtcyogcFBhcmFtcyA9IChjb21wX3BhcmFtcyopd2FzbV9wdHIocGFyYW1zX29mcyk7CglpZiAoIXBQYXJhbXMpCgkJcmV0dXJuIGZhbHNlOwoKCWFzc2VydChwUGFyYW1zLT5tX21hZ2ljID09IENPTVBfUEFSQU1TX01BR0lDKTsKCWlmIChwUGFyYW1zLT5tX21hZ2ljICE9IENPTVBfUEFSQU1TX01BR0lDKQoJCXJldHVybiBmYWxzZTsKCglwUGFyYW1zLT5jbGVhcigpOwoKCXJldHVybiB0cnVlOwp9CgovLyBDYWxsZXIgd2FudHMgdG8gZ2l2ZSB1cyBhIExEUi9TRFIgMzJicHAgUkdCQSBtaXBtYXAgbGV2ZWwgKDQgYnl0ZXMgcGVyIHBpeGVsKQpCVV9XQVNNX0VYUE9SVCgiYnVfY29tcF9wYXJhbXNfc2V0X2ltYWdlX3JnYmEzMiIpCndhc21fYm9vbF90IGJ1X2NvbXBfcGFyYW1zX3NldF9pbWFnZV9yZ2JhMzIoCgl1aW50NjRfdCBwYXJhbXNfb2ZzLAoJdWludDMyX3QgaW1hZ2VfaW5kZXgsCgl1aW50NjRfdCBpbWdfZGF0YV9vZnMsCgl1aW50MzJfdCB3aWR0aCwgdWludDMyX3QgaGVpZ2h0LAoJdWludDMyX3QgcGl0Y2hfaW5fYnl0ZXMpCnsKCWlmICgoIXdpZHRoKSB8fCAoIWhlaWdodCkgfHwgKCFwaXRjaF9pbl9ieXRlcykpCgkJcmV0dXJuIGZhbHNlOwoKCWNvbXBfcGFyYW1zKiBwUGFyYW1zID0gKGNvbXBfcGFyYW1zKil3YXNtX3B0cihwYXJhbXNfb2ZzKTsKCWlmICghcFBhcmFtcykKCQlyZXR1cm4gZmFsc2U7CgoJYXNzZXJ0KHBQYXJhbXMtPm1fbWFnaWMgPT0gQ09NUF9QQVJBTVNfTUFHSUMpOwoJaWYgKHBQYXJhbXMtPm1fbWFnaWMgIT0gQ09NUF9QQVJBTVNfTUFHSUMpCgkJcmV0dXJuIGZhbHNlOwoJCQoJY29uc3QgdWludDhfdCogcEltYWdlID0gd2FzbV9wdHIoaW1nX2RhdGFfb2ZzKTsKCWlmICghcEltYWdlKQoJCXJldHVybiBmYWxzZTsKCgljb25zdCB1aW50MzJfdCBieXRlc19wZXJfcGl4ZWwgPSBzaXplb2YoY29sb3JfcmdiYSk7CgoJaWYgKHBpdGNoX2luX2J5dGVzIDwgd2lkdGggKiBieXRlc19wZXJfcGl4ZWwpCgkJcmV0dXJuIGZhbHNlOwoKCWlmIChpbWFnZV9pbmRleCA+PSBwUGFyYW1zLT5tX2ltYWdlcy5zaXplKCkpCgl7CgkJaWYgKCFwUGFyYW1zLT5tX2ltYWdlcy50cnlfcmVzaXplKGltYWdlX2luZGV4ICsgMSkpCgkJCXJldHVybiBmYWxzZTsKCX0KCgliYXNpc3U6OmltYWdlJiBkc3RfaW1nID0gcFBhcmFtcy0+bV9pbWFnZXNbaW1hZ2VfaW5kZXhdOwoKCWRzdF9pbWcucmVzaXplKHdpZHRoLCBoZWlnaHQpOwoJCQoJaWYgKHBpdGNoX2luX2J5dGVzID09IHdpZHRoICogYnl0ZXNfcGVyX3BpeGVsKQoJewoJCW1lbWNweShkc3RfaW1nLmdldF9wdHIoKSwgcEltYWdlLCBwaXRjaF9pbl9ieXRlcyAqIGhlaWdodCk7Cgl9CgllbHNlCgl7CgkJZm9yICh1aW50MzJfdCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKQoJCXsKCQkJY29uc3QgdWludDhfdCogcFNyY19yb3cgPSBwSW1hZ2UgKyB5ICogcGl0Y2hfaW5fYnl0ZXM7CgkJCQoJCQl1aW50OF90KiBwRHN0X3JvdyA9ICh1aW50OF90ICopJmRzdF9pbWcoMCwgeSk7CgoJCQltZW1jcHkocERzdF9yb3csIHBTcmNfcm93LCB3aWR0aCAqIGJ5dGVzX3Blcl9waXhlbCk7CgkJfSAvLyB5Cgl9CgoJcmV0dXJuIHRydWU7Cn0KCi8vIENhbGxlciB3YW50cyB0byBnaXZlIHVzIGEgZmxvYXQgUkdCQSBtaXBtYXAgbGV2ZWwgKDQqND0xNiBieXRlcyBwZXIgcGl4ZWwpCkJVX1dBU01fRVhQT1JUKCJidV9jb21wX3BhcmFtc19zZXRfaW1hZ2VfZmxvYXRfcmdiYSIpCndhc21fYm9vbF90IGJ1X2NvbXBfcGFyYW1zX3NldF9pbWFnZV9mbG9hdF9yZ2JhKAoJdWludDY0X3QgcGFyYW1zX29mcywKCXVpbnQzMl90IGltYWdlX2luZGV4LAoJdWludDY0X3QgaW1nX2RhdGFfb2ZzLAoJdWludDMyX3Qgd2lkdGgsIHVpbnQzMl90IGhlaWdodCwKCXVpbnQzMl90IHBpdGNoX2luX2J5dGVzKQp7CglpZiAoKCF3aWR0aCkgfHwgKCFoZWlnaHQpIHx8ICghcGl0Y2hfaW5fYnl0ZXMpKQoJCXJldHVybiBmYWxzZTsKCgljb21wX3BhcmFtcyogcFBhcmFtcyA9IChjb21wX3BhcmFtcyopd2FzbV9wdHIocGFyYW1zX29mcyk7CglpZiAoIXBQYXJhbXMpCgkJcmV0dXJuIGZhbHNlOwoKCWFzc2VydChwUGFyYW1zLT5tX21hZ2ljID09IENPTVBfUEFSQU1TX01BR0lDKTsKCWlmIChwUGFyYW1zLT5tX21hZ2ljICE9IENPTVBfUEFSQU1TX01BR0lDKQoJCXJldHVybiBmYWxzZTsKCgljb25zdCB1aW50OF90KiBwSW1hZ2UgPSB3YXNtX3B0cihpbWdfZGF0YV9vZnMpOwoJaWYgKCFwSW1hZ2UpCgkJcmV0dXJuIGZhbHNlOwoKCWNvbnN0IHVpbnQzMl90IGJ5dGVzX3Blcl9waXhlbCA9IHNpemVvZihmbG9hdCkgKiA0OwoKCWlmIChwaXRjaF9pbl9ieXRlcyA8IHdpZHRoICogYnl0ZXNfcGVyX3BpeGVsKQoJCXJldHVybiBmYWxzZTsKCglpZiAoaW1hZ2VfaW5kZXggPj0gcFBhcmFtcy0+bV9pbWFnZXNmLnNpemUoKSkKCXsKCQlpZiAoIXBQYXJhbXMtPm1faW1hZ2VzZi50cnlfcmVzaXplKGltYWdlX2luZGV4ICsgMSkpCgkJCXJldHVybiBmYWxzZTsKCX0KCgliYXNpc3U6OmltYWdlZiYgZHN0X2ltZyA9IHBQYXJhbXMtPm1faW1hZ2VzZltpbWFnZV9pbmRleF07CgoJZHN0X2ltZy5yZXNpemUod2lkdGgsIGhlaWdodCk7CgoJaWYgKHBpdGNoX2luX2J5dGVzID09IHdpZHRoICogYnl0ZXNfcGVyX3BpeGVsKQoJewoJCW1lbWNweSgodm9pZCAqKWRzdF9pbWcuZ2V0X3B0cigpLCAoY29uc3Qgdm9pZCAqKXBJbWFnZSwgcGl0Y2hfaW5fYnl0ZXMgKiBoZWlnaHQpOwoJfQoJZWxzZQoJewoJCWZvciAodWludDMyX3QgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykKCQl7CgkJCWNvbnN0IHVpbnQ4X3QqIHBTcmNfcm93ID0gcEltYWdlICsgeSAqIHBpdGNoX2luX2J5dGVzOwoKCQkJdWludDhfdCogcERzdF9yb3cgPSAodWludDhfdCopJmRzdF9pbWcoMCwgeSk7CgoJCQltZW1jcHkocERzdF9yb3csIHBTcmNfcm93LCB3aWR0aCAqIGJ5dGVzX3Blcl9waXhlbCk7CgkJfSAvLyB5Cgl9CgoJcmV0dXJuIHRydWU7Cn0KCkJVX1dBU01fRVhQT1JUKCJidV9jb21wcmVzc190ZXh0dXJlIikKd2FzbV9ib29sX3QgYnVfY29tcHJlc3NfdGV4dHVyZSgKCXVpbnQ2NF90IHBhcmFtc19vZnMsCgl1aW50MzJfdCBkZXNpcmVkX2Jhc2lzX3RleF9mb3JtYXQsIC8vIGJhc2lzX3RleF9mb3JtYXQKCWludCBxdWFsaXR5X2xldmVsLCBpbnQgZWZmb3J0X2xldmVsLAoJdWludDY0X3QgZmxhZ3NfYW5kX3F1YWxpdHksIGZsb2F0IGxvd19sZXZlbF91YXN0Y19yZG9fb3JfZGN0X3F1YWxpdHkpCnsKCS8vZW5hYmxlX2RlYnVnX3ByaW50ZigoZmxhZ3NfYW5kX3F1YWxpdHkgJiBjRmxhZ0RlYnVnKSAhPSAwKTsKCgljb21wX3BhcmFtcyogcFBhcmFtcyA9IChjb21wX3BhcmFtcyopd2FzbV9wdHIocGFyYW1zX29mcyk7CglpZiAoIXBQYXJhbXMpCgkJcmV0dXJuIGZhbHNlOwoKCWFzc2VydChwUGFyYW1zLT5tX21hZ2ljID09IENPTVBfUEFSQU1TX01BR0lDKTsKCWlmIChwUGFyYW1zLT5tX21hZ2ljICE9IENPTVBfUEFSQU1TX01BR0lDKQoJCXJldHVybiBmYWxzZTsKCglwUGFyYW1zLT5tX2NvbXBfZGF0YS5jbGVhcigpOwoKCWlmIChkZXNpcmVkX2Jhc2lzX3RleF9mb3JtYXQgPj0gKHVpbnQzMl90KWJhc2lzdDo6YmFzaXNfdGV4X2Zvcm1hdDo6Y1RvdGFsRm9ybWF0cykKCQlyZXR1cm4gZmFsc2U7CgoJaWYgKCFwUGFyYW1zLT5tX2ltYWdlcy5zaXplKCkgJiYgIXBQYXJhbXMtPm1faW1hZ2VzZi5zaXplKCkpCgkJcmV0dXJuIGZhbHNlOwoJaWYgKHBQYXJhbXMtPm1faW1hZ2VzLnNpemUoKSAmJiBwUGFyYW1zLT5tX2ltYWdlc2Yuc2l6ZSgpKQoJCXJldHVybiBmYWxzZTsKCglzaXplX3QgY29tcF9zaXplID0gMDsKCQoJdm9pZCogcENvbXBfZGF0YSA9IGJhc2lzX2NvbXByZXNzX2ludGVybmFsKAoJCShiYXNpc3Q6OmJhc2lzX3RleF9mb3JtYXQpZGVzaXJlZF9iYXNpc190ZXhfZm9ybWF0LAoJCXBQYXJhbXMtPm1faW1hZ2VzLnNpemUoKSA/ICZwUGFyYW1zLT5tX2ltYWdlcyA6IG51bGxwdHIsCgkJcFBhcmFtcy0+bV9pbWFnZXNmLnNpemUoKSA/ICZwUGFyYW1zLT5tX2ltYWdlc2YgOiBudWxscHRyLAoJCSh1aW50MzJfdClmbGFnc19hbmRfcXVhbGl0eSwKCQlsb3dfbGV2ZWxfdWFzdGNfcmRvX29yX2RjdF9xdWFsaXR5LAoJCSZjb21wX3NpemUsCgkJJnBQYXJhbXMtPm1fc3RhdHMsCgkJcXVhbGl0eV9sZXZlbCwKCQllZmZvcnRfbGV2ZWwpOwoKCWlmICghcENvbXBfZGF0YSkKCQlyZXR1cm4gZmFsc2U7CgoJaWYgKCFwUGFyYW1zLT5tX2NvbXBfZGF0YS50cnlfcmVzaXplKGNvbXBfc2l6ZSkpCgl7CgkJYmFzaXNfZnJlZV9kYXRhKHBDb21wX2RhdGEpOwoJCXJldHVybiBmYWxzZTsKCX0KCQoJbWVtY3B5KHBQYXJhbXMtPm1fY29tcF9kYXRhLmdldF9wdHIoKSwgcENvbXBfZGF0YSwgY29tcF9zaXplKTsKCgliYXNpc19mcmVlX2RhdGEocENvbXBfZGF0YSk7CgoJcmV0dXJuIHRydWU7Cn0K