LyoKICogKEMpCUNvcHlyaWdodCAyMDAxCiAqIFN05HVibGkgRmF2ZXJnZXMgLSA8d3d3LnN0YXVibGkuY29tPgogKiBQaWVycmUgQVVCRVJUICBwLmF1YmVydEBzdGF1YmxpLmNvbQogKiBVLUJvb3QgcG9ydCBvbiBSUFhDbGFzc2ljIExGIChDTExGX0JXMzEpIGJvYXJkCiAqCiAqIChDKSBDb3B5cmlnaHQgMjAwMAogKiBXb2xmZ2FuZyBEZW5rLCBERU5YIFNvZnR3YXJlIEVuZ2luZWVyaW5nLCB3ZEBkZW54LmRlLgogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgkgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGkyYy5oPgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxtcGM4eHguaD4KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYyBsb25nIGludCBkcmFtX3NpemUgKGxvbmcgaW50LCBsb25nIGludCAqLCBsb25nIGludCk7CnN0YXRpYyB1bnNpZ25lZCBjaGFyIGFzY2hleF90b19ieXRlICh1bnNpZ25lZCBjaGFyICpjcCk7CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojZGVmaW5lIF9OT1RfVVNFRF8JMHhGRkZGQ0MyNQoKY29uc3QgdWludCBzZHJhbV90YWJsZVtdID0KewoJLyoKCSAqIFNpbmdsZSBSZWFkLiAoT2Zmc2V0IDAwaCBpbiBVUE1BIFJBTSkKCSAqLwoJMHhDRkZGQ0MyNCwgMHgwRkZGQ0MwNCwgMFgwQ0FGQ0MwNCwgMFgwM0FGQ0MwOCwKCTB4M0ZCRkNDMjcsIC8qIGxhc3QgKi8KCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCgoJLyoKCSAqIEJ1cnN0IFJlYWQuIChPZmZzZXQgMDhoIGluIFVQTUEgUkFNKQoJICovCgkweENGRkZDQzI0LCAweDBGRkZDQzA0LCAweDBDQUZDQzg0LCAweDAzQUZDQzg4LAoJMHgzRkJGQ0MyNywgLyogbGFzdCAqLwoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLAoKCS8qCgkgKiBTaW5nbGUgV3JpdGUuIChPZmZzZXQgMThoIGluIFVQTUEgUkFNKQoJICovCgkweENGRkZDQzI0LCAweDBGRkZDQzA0LCAweDBDRkZDQzA0LCAweDAzRkZDQzAwLAoJMHgzRkZGQ0MyNywgLyogbGFzdCAqLwoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCgkvKgoJICogQnVyc3QgV3JpdGUuIChPZmZzZXQgMjBoIGluIFVQTUEgUkFNKQoJICovCgkweENGRkZDQzI0LCAweDBGRkZDQzA0LCAweDBDRkZDQzgwLCAweDAzRkZDQzhDLAoJMHgwQ0ZGQ0MwMCwgMHgzM0ZGQ0MyNywgLyogbGFzdCAqLwoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLAoKCS8qCgkgKiBSZWZyZXNoLiAoT2Zmc2V0IDMwaCBpbiBVUE1BIFJBTSkKCSAqLwoJMHhDMEZGQ0MyNCwgMHgwM0ZGQ0MyNCwgMHgwRkZGQ0MyNCwgMHgwRkZGQ0MyNCwKCTB4M0ZGRkNDMjcsIC8qIGxhc3QgKi8KCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLAoKCS8qCgkgKiBFeGNlcHRpb24uIChPZmZzZXQgM0NoIGluIFVQTUEgUkFNKQoJICovCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfCn07CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgoKLyoKICogQ2hlY2sgQm9hcmQgSWRlbnRpdHk6CiAqLwoKaW50IGNoZWNrYm9hcmQgKHZvaWQpCnsKCXB1dHMgKCJCb2FyZDogUlBYQ2xhc3NpY1xuIik7CglyZXR1cm4gKDApOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIGJvYXJkX2dldF9lbmV0YWRkciAtLSBSZWFkIHRoZSBNQUMgQWRkcmVzcyBpbiB0aGUgSTJDIEVFUFJPTQogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwp2b2lkIGJvYXJkX2dldF9lbmV0YWRkciAodWNoYXIgKiBlbmV0KQp7CglpbnQgaTsKCWNoYXIgYnVmZlsyNTZdLCAqY3A7CgoJLyogSW5pdGlhbGl6ZSBJMkMJCQkJCSovCglpMmNfaW5pdCAoQ09ORklHX1NZU19JMkNfU1BFRUQsIENPTkZJR19TWVNfSTJDX1NMQVZFKTsKCgkvKiBSZWFkIDI1NiBieXRlcyBpbiBFRVBST00JCQkJKi8KCWkyY19yZWFkICgweDU0LCAwLCAxLCAodWNoYXIgKilidWZmLCAxMjgpOwoJaTJjX3JlYWQgKDB4NTQsIDEyOCwgMSwgKHVjaGFyICopYnVmZiArIDEyOCwgMTI4KTsKCgkvKiBSZXRyaWV2ZSBNQUMgYWRkcmVzcyBpbiBidWZmZXIgKGtleSBFQSkJCSovCglmb3IgKGNwID0gYnVmZjs7KSB7CgkJaWYgKGNwWzBdID09ICdFJyAmJiBjcFsxXSA9PSAnQScpIHsKCQkJY3AgKz0gMzsKCQkJLyogUmVhZCBNQUMgYWRkcmVzcwkJCSovCgkJCWZvciAoaSA9IDA7IGkgPCA2OyBpKyssIGNwICs9IDIpIHsKCQkJCWVuZXRbaV0gPSBhc2NoZXhfdG9fYnl0ZSAoKHVuc2lnbmVkIGNoYXIgKiljcCk7CgkJCX0KCQl9CgkJLyogU2NhbiB0byB0aGUgZW5kIG9mIHRoZSByZWNvcmQJCSovCgkJd2hpbGUgKCgqY3AgIT0gJ1xuJykgJiYgKCpjcCAhPSAoY2hhcikweGZmKSkgewoJCQljcCsrOwoJCX0KCQkvKiBJZiB0aGUgbmV4dCBjaGFyYWN0ZXIgaXMgYSBcbiwgMCBvciBmZiwgd2UgYXJlIGRvbmUuCSovCgkJY3ArKzsKCQlpZiAoKCpjcCA9PSAnXG4nKSB8fCAoKmNwID09IDApIHx8ICgqY3AgPT0gKGNoYXIpMHhmZikpCgkJCWJyZWFrOwoJfQoKI2lmZGVmIENPTkZJR19GRUNfRU5FVAoJLyogVGhlIE1BQyBhZGRyZXNzIGlzIHRoZSBzYW1lIGFzIG5vcm1hbCBldGhlcm5ldCBleGNlcHQgdGhlIDNyZCBieXRlCSAqLwoJLyogKFNlZSB0aGUgRS5QLiBQbGFuZXQgQ29yZSBPdmVydmlldyBtYW51YWwJCSovCgllbmV0WzNdIHw9IDB4ODA7CiNlbmRpZgoKCXByaW50ZiAoIk1BQyBhZGRyZXNzID0gJTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4OiUwMnhcbiIsCgkJZW5ldFswXSwgZW5ldFsxXSwgZW5ldFsyXSwgZW5ldFszXSwgZW5ldFs0XSwgZW5ldFs1XSk7Cgp9Cgp2b2lkIHJweGNsYXNzaWNfaW5pdCAodm9pZCkKewoJLyogRW5hYmxlIE5WUkFNICovCgkqKCh1Y2hhciAqKSBCQ1NSMCkgfD0gQkNTUjBfRU5OVlJBTTsKCiNpZmRlZiBDT05GSUdfRkVDX0VORVQKCgkvKiBWYWxpZGF0ZSB0aGUgZmFzdCBldGhlcm5ldCB0cmFuY2VpdmVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwoJKigodm9sYXRpbGUgdWNoYXIgKikgQkNTUjIpICY9IH5CQ1NSMl9NSUlDVEw7CgkqKCh2b2xhdGlsZSB1Y2hhciAqKSBCQ1NSMikgJj0gfkJDU1IyX01JSVBXUkRXTjsKCSooKHZvbGF0aWxlIHVjaGFyICopIEJDU1IyKSB8PSBCQ1NSMl9NSUlSU1Q7CgkqKCh2b2xhdGlsZSB1Y2hhciAqKSBCQ1NSMikgfD0gQkNTUjJfTUlJUFdSRFdOOwojZW5kaWYKCn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnBoeXNfc2l6ZV90IGluaXRkcmFtIChpbnQgYm9hcmRfdHlwZSkKewoJdm9sYXRpbGUgaW1tYXBfdCAqaW1tYXAgPSAoaW1tYXBfdCAqKSBDT05GSUdfU1lTX0lNTVI7Cgl2b2xhdGlsZSBtZW1jdGw4eHhfdCAqbWVtY3RsID0gJmltbWFwLT5pbV9tZW1jdGw7Cglsb25nIGludCBzaXplMTA7CgoJdXBtY29uZmlnIChVUE1BLCAodWludCAqKSBzZHJhbV90YWJsZSwKCQkJICAgc2l6ZW9mIChzZHJhbV90YWJsZSkgLyBzaXplb2YgKHVpbnQpKTsKCgkvKiBSZWZyZXNoIGNsb2NrIHByZXNjYWxhciAqLwoJbWVtY3RsLT5tZW1jX21wdHByID0gQ09ORklHX1NZU19NUFRQUjsKCgltZW1jdGwtPm1lbWNfbWFyID0gMHgwMDAwMDAwMDsKCgkvKiBNYXAgY29udHJvbGxlciBiYW5rcyAxIHRvIHRoZSBTRFJBTSBiYW5rICovCgltZW1jdGwtPm1lbWNfb3IxID0gQ09ORklHX1NZU19PUjFfUFJFTElNOwoJbWVtY3RsLT5tZW1jX2JyMSA9IENPTkZJR19TWVNfQlIxX1BSRUxJTTsKCgltZW1jdGwtPm1lbWNfbWFtciA9IENPTkZJR19TWVNfTUFNUl8xMENPTCAmICh+KE1BTVJfUFRBRSkpOwkvKiBubyByZWZyZXNoIHlldCAqLwoKCXVkZWxheSAoMjAwKTsKCgkvKiBwZXJmb3JtIFNEUkFNIGluaXRpYWxpenNhdGlvbiBzZXF1ZW5jZSAqLwoKCW1lbWN0bC0+bWVtY19tY3IgPSAweDgwMDAyMjMwOwkvKiBTRFJBTSBiYW5rIDAgLSByZWZyZXNoIHR3aWNlICovCgl1ZGVsYXkgKDEpOwoKCW1lbWN0bC0+bWVtY19tYW1yIHw9IE1BTVJfUFRBRTsgLyogZW5hYmxlIHJlZnJlc2ggKi8KCgl1ZGVsYXkgKDEwMDApOwoKCS8qIENoZWNrIEJhbmsgMCBNZW1vcnkgU2l6ZQoJICogdHJ5IDEwIGNvbHVtbiBtb2RlCgkgKi8KCglzaXplMTAgPSBkcmFtX3NpemUgKENPTkZJR19TWVNfTUFNUl8xMENPTCwgU0RSQU1fQkFTRV9QUkVMSU0sCgkJCQkJCVNEUkFNX01BWF9TSVpFKTsKCglyZXR1cm4gKHNpemUxMCk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qCiAqIENoZWNrIG1lbW9yeSByYW5nZSBmb3IgdmFsaWQgUkFNLiBBIHNpbXBsZSBtZW1vcnkgdGVzdCBkZXRlcm1pbmVzCiAqIHRoZSBhY3R1YWxseSBhdmFpbGFibGUgUkFNIHNpemUgYmV0d2VlbiBhZGRyZXNzZXMgYGJhc2UnIGFuZAogKiBgYmFzZSArIG1heHNpemUnLiBTb21lIChub3QgYWxsKSBoYXJkd2FyZSBlcnJvcnMgYXJlIGRldGVjdGVkOgogKiAtIHNob3J0IGJldHdlZW4gYWRkcmVzcyBsaW5lcwogKiAtIHNob3J0IGJldHdlZW4gZGF0YSBsaW5lcwogKi8KCnN0YXRpYyBsb25nIGludCBkcmFtX3NpemUgKGxvbmcgaW50IG1hbXJfdmFsdWUsIGxvbmcgaW50ICpiYXNlLCBsb25nIGludCBtYXhzaXplKQp7Cgl2b2xhdGlsZSBpbW1hcF90ICppbW1hcCA9IChpbW1hcF90ICopIENPTkZJR19TWVNfSU1NUjsKCXZvbGF0aWxlIG1lbWN0bDh4eF90ICptZW1jdGwgPSAmaW1tYXAtPmltX21lbWN0bDsKCgltZW1jdGwtPm1lbWNfbWFtciA9IG1hbXJfdmFsdWU7CgoJcmV0dXJuIChnZXRfcmFtX3NpemUoYmFzZSwgbWF4c2l6ZSkpOwp9Ci8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogYXNjaGV4X3RvX2J5dGUgLS0KICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIgYXNjaGV4X3RvX2J5dGUgKHVuc2lnbmVkIGNoYXIgKmNwKQp7Cgl1X2NoYXIgYnl0ZSwgYzsKCgljID0gKmNwKys7CgoJaWYgKChjID49ICdBJykgJiYgKGMgPD0gJ0YnKSkgewoJCWMgLT0gJ0EnOwoJCWMgKz0gMTA7Cgl9IGVsc2UgaWYgKChjID49ICdhJykgJiYgKGMgPD0gJ2YnKSkgewoJCWMgLT0gJ2EnOwoJCWMgKz0gMTA7Cgl9IGVsc2UgewoJCWMgLT0gJzAnOwoJfQoKCWJ5dGUgPSBjICogMTY7CgoJYyA9ICpjcDsKCglpZiAoKGMgPj0gJ0EnKSAmJiAoYyA8PSAnRicpKSB7CgkJYyAtPSAnQSc7CgkJYyArPSAxMDsKCX0gZWxzZSBpZiAoKGMgPj0gJ2EnKSAmJiAoYyA8PSAnZicpKSB7CgkJYyAtPSAnYSc7CgkJYyArPSAxMDsKCX0gZWxzZSB7CgkJYyAtPSAnMCc7Cgl9CgoJYnl0ZSArPSBjOwoKCXJldHVybiAoYnl0ZSk7Cn0K