IC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIHNtYzkwMDAuYwogKiBUaGlzIGlzIGEgRXRoZXJib290IGRyaXZlciBmb3IgU01DJ3MgOTAwMCBzZXJpZXMgb2YgRXRoZXJuZXQgY2FyZHMuCiAqCiAqIENvcHlyaWdodCAoQykgMTk5OCBEYW5pZWwgRW5nc3Ry9m0gPGRhbmllbC5lbmdzdHJvbUByaWtzbmV0dC5ubz4KICogQmFzZWQgb24gdGhlIExpbnV4IFNNQzkwMDAgZHJpdmVyLCBzbWM5MTk0LmMgYnkgRXJpYyBTdGFobG1hbgogKiBDb3B5cmlnaHQgKEMpIDE5OTYgYnkgRXJpayBTdGFobG1hbiA8ZXJpY0B2dC5lZHU+CiAqCiAqIFRoaXMgc29mdHdhcmUgbWF5IGJlIHVzZWQgYW5kIGRpc3RyaWJ1dGVkIGFjY29yZGluZyB0byB0aGUgdGVybXMKICogb2YgdGhlIEdOVSBQdWJsaWMgTGljZW5zZSwgaW5jb3Jwb3JhdGVkIGhlcmVpbiBieSByZWZlcmVuY2UuCiAqCiAqICJGZWF0dXJlcyIgb2YgdGhlIFNNQyBjaGlwOgogKiAgIDQ2MDggYnl0ZSBwYWNrZXQgbWVtb3J5LiAoIGZvciB0aGUgOTFDOTIvNC4gIE90aGVycyBoYXZlIG1vcmUgKQogKiAgIEVFUFJPTSBmb3IgY29uZmlndXJhdGlvbgogKiAgIEFVSS9UUCBzZWxlY3Rpb24KICoKICogQXV0aG9ycwogKglFcmlrIFN0YWhsbWFuCQkJCTxlcmlrQHZ0LmVkdT4KICogICAgICBEYW5pZWwgRW5nc3Ry9m0gICAgICAgICAgICAgICAgICAgICAgICAgPGRhbmllbC5lbmdzdHJvbUByaWtzbmV0dC5ubz4KICoKICogSGlzdG9yeQogKiA5OC0wOS0yNSAgICAgICAgICAgICAgRGFuaWVsIEVuZ3N0cvZtIEV0aGVyYm9vdCBkcml2ZXIgY3JhdGVkIGZyb20gRXJpYydzCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGludXggZHJpdmVyLgogKgogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCiNkZWZpbmUgTElOVVhfT1VUX01BQ1JPUyAxCiNkZWZpbmUgU01DOTAwMF9WRVJCT1NFICAxCiNkZWZpbmUgU01DOTAwMF9ERUJVRyAgICAwCgojaW5jbHVkZSAiZXRoZXJib290LmgiCiNpbmNsdWRlICJuaWMuaCIKI2luY2x1ZGUgImNhcmRzLmgiCiNpbmNsdWRlICJzbWM5MDAwLmgiCgojIGRlZmluZSBfb3V0YiBvdXRiCiMgZGVmaW5lIF9vdXR3IG91dHcKCnN0YXRpYyBjb25zdCBjaGFyICAgICAgIHNtYzkwMDBfdmVyc2lvbltdID0gIlZlcnNpb24gMC45OSA5OC0wOS0zMCI7CnN0YXRpYyB1bnNpZ25lZCBpbnQJc21jOTAwMF9iYXNlPTA7CnN0YXRpYyBjb25zdCBjaGFyICAgICAgICppbnRlcmZhY2VzWyAyIF0gPSB7ICJUUCIsICJBVUkiIH07CnN0YXRpYyBjb25zdCBjaGFyICAgICAgICpjaGlwX2lkc1sgMTUgXSA9ICB7CiAgIE5VTEwsIE5VTEwsIE5VTEwsCiAgIC8qIDMgKi8gIlNNQzkxQzkwLzkxQzkyIiwKICAgLyogNCAqLyAiU01DOTFDOTQiLAogICAvKiA1ICovICJTTUM5MUM5NSIsCiAgIE5VTEwsCiAgIC8qIDcgKi8gIlNNQzkxQzEwMCIsCiAgIC8qIDggKi8gIlNNQzkxQzEwMEZEIiwKICAgTlVMTCwgTlVMTCwgTlVMTCwKICAgTlVMTCwgTlVMTCwgTlVMTAp9OwpzdGF0aWMgY29uc3QgY2hhciAgICAgIHNtYzkxYzk2X2lkW10gPSAiU01DOTFDOTYiOwoKLyoKICogRnVuY3Rpb246IHNtY19yZXNldCggaW50IGlvYWRkciApCiAqIFB1cnBvc2U6CiAqCVRoaXMgc2V0cyB0aGUgU01DOTF4eCBjaGlwIHRvIGl0cyBub3JtYWwgc3RhdGUsIGhvcGVmdWxseSBmcm9tIHdoYXRldmVyCiAqCW1lc3MgdGhhdCBhbnkgb3RoZXIgRE9TIGRyaXZlciBoYXMgcHV0IGl0IGluLgogKgogKiBNYXliZSBJIHNob3VsZCByZXNldCBtb3JlIHJlZ2lzdGVycyB0byBkZWZhdWx0cyBpbiBoZXJlPyAgU09GVFJFU0VUICBzaG91bGQKICogZG8gdGhhdCBmb3IgbWUuCiAqCiAqIE1ldGhvZDoKICoJMS4gIHNlbmQgYSBTT0ZUIFJFU0VUCiAqCTIuICB3YWl0IGZvciBpdCB0byBmaW5pc2gKICoJMy4gIHJlc2V0IHRoZSBtZW1vcnkgbWFuYWdlbWVudCB1bml0CiAqICAgICAgNC4gIGNsZWFyIGFsbCBpbnRlcnJ1cHRzCiAqCiovCnN0YXRpYyB2b2lkIHNtY19yZXNldChpbnQgaW9hZGRyKQp7CiAgIC8qIFRoaXMgcmVzZXRzIHRoZSByZWdpc3RlcnMgbW9zdGx5IHRvIGRlZmF1bHRzLCBidXQgZG9lc24ndAogICAgKiBhZmZlY3QgRUVQUk9NLiAgVGhhdCBzZWVtcyB1bm5lY2Vzc2FyeSAqLwogICBTTUNfU0VMRUNUX0JBTksoaW9hZGRyLCAwKTsKICAgX291dHcoIFJDUl9TT0ZUUkVTRVQsIGlvYWRkciArIFJDUiApOwoKICAgLyogdGhpcyBzaG91bGQgcGF1c2UgZW5vdWdoIGZvciB0aGUgY2hpcCB0byBiZSBoYXBweSAqLwogICBTTUNfREVMQVkoaW9hZGRyKTsKCiAgIC8qIFNldCB0aGUgdHJhbnNtaXQgYW5kIHJlY2VpdmUgY29uZmlndXJhdGlvbiByZWdpc3RlcnMgdG8KICAgICogZGVmYXVsdCB2YWx1ZXMgKi8KICAgX291dHcoUkNSX0NMRUFSLCBpb2FkZHIgKyBSQ1IpOwogICBfb3V0dyhUQ1JfQ0xFQVIsIGlvYWRkciArIFRDUik7CgogICAvKiBSZXNldCB0aGUgTU1VICovCiAgIFNNQ19TRUxFQ1RfQkFOSyhpb2FkZHIsIDIpOwogICBfb3V0dyggTUNfUkVTRVQsIGlvYWRkciArIE1NVV9DTUQgKTsKCiAgIC8qIE5vdGU6ICBJdCBkb2Vzbid0IHNlZW0gdGhhdCB3YWl0aW5nIGZvciB0aGUgTU1VIGJ1c3kgaXMgbmVlZGVkIGhlcmUsCiAgICAqIGJ1dCB0aGlzIGlzIGEgcGxhY2Ugd2hlcmUgZnV0dXJlIGNoaXBzZXRzIF9DT1VMRF8gYnJlYWsuICBCZSB3YXJ5CiAgICAqIG9mIGlzc3VpbmcgYW5vdGhlciBNTVUgY29tbWFuZCByaWdodCBhZnRlciB0aGlzICovCiAgIF9vdXRiKDAsIGlvYWRkciArIElOVF9NQVNLKTsKfQoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBGdW5jdGlvbjogc21jX3Byb2JlKCBpbnQgaW9hZGRyICkKICoKICogUHVycG9zZToKICoJVGVzdHMgdG8gc2VlIGlmIGEgZ2l2ZW4gaW9hZGRyIHBvaW50cyB0byBhbiBTTUM5eHh4IGNoaXAuCiAqCVJldHVybnMgYSAwIG9uIHN1Y2Nlc3MKICoKICogQWxnb3JpdGhtOgogKgkoMSkgc2VlIGlmIHRoZSBoaWdoIGJ5dGUgb2YgQkFOS19TRUxFQ1QgaXMgMHgzMwogKgkoMikgY29tcGFyZSB0aGUgaW9hZGRyIHdpdGggdGhlIGJhc2UgcmVnaXN0ZXIncyBhZGRyZXNzCiAqCSgzKSBzZWUgaWYgSSByZWNvZ25pemUgdGhlIGNoaXAgSUQgaW4gdGhlIGFwcHJvcHJpYXRlIHJlZ2lzdGVyCiAqCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8Kc3RhdGljIGludCBzbWNfcHJvYmUoIGludCBpb2FkZHIgKQp7CiAgIHdvcmQgYmFuazsKICAgd29yZAlyZXZpc2lvbl9yZWdpc3RlcjsKICAgd29yZCBiYXNlX2FkZHJlc3NfcmVnaXN0ZXI7CgogICAvKiBGaXJzdCwgc2VlIGlmIHRoZSBoaWdoIGJ5dGUgaXMgMHgzMyAqLwogICBiYW5rID0gaW53KGlvYWRkciArIEJBTktfU0VMRUNUKTsKICAgaWYgKChiYW5rICYgMHhGRjAwKSAhPSAweDMzMDApIHsKICAgICAgcmV0dXJuIC0xOwogICB9CiAgIC8qIFRoZSBhYm92ZSBNSUdIVCBpbmRpY2F0ZSBhIGRldmljZSwgYnV0IEkgbmVlZCB0byB3cml0ZSB0byBmdXJ0aGVyCiAgICAqCXRlc3QgdGhpcy4gICovCiAgIF9vdXR3KDB4MCwgaW9hZGRyICsgQkFOS19TRUxFQ1QpOwogICBiYW5rID0gaW53KGlvYWRkciArIEJBTktfU0VMRUNUKTsKICAgaWYgKChiYW5rICYgMHhGRjAwKSAhPSAweDMzMDApIHsKICAgICAgcmV0dXJuIC0xOwogICB9CgogICAvKiB3ZWxsLCB3ZSd2ZSBhbHJlYWR5IHdyaXR0ZW4gb25jZSwgc28gaG9wZWZ1bGx5IGFub3RoZXIgdGltZSB3b24ndAogICAgKiAgaHVydC4gIFRoaXMgdGltZSwgSSBuZWVkIHRvIHN3aXRjaCB0aGUgYmFuayByZWdpc3RlciB0byBiYW5rIDEsCiAgICAqICBzbyBJIGNhbiBhY2Nlc3MgdGhlIGJhc2UgYWRkcmVzcyByZWdpc3RlciAqLwogICBTTUNfU0VMRUNUX0JBTksoaW9hZGRyLCAxKTsKICAgYmFzZV9hZGRyZXNzX3JlZ2lzdGVyID0gaW53KGlvYWRkciArIEJBU0UpOwoKICAgaWYgKGlvYWRkciAhPSAoYmFzZV9hZGRyZXNzX3JlZ2lzdGVyID4+IDMgJiAweDNFMCkpICB7CiNpZmRlZglTTUM5MDAwX1ZFUkJPU0UKICAgICAgcHJpbnRmKCJTTUM5MDAwOiBJT0FERFIgJWhYIGRvZXNuJ3QgbWF0Y2ggY29uZmlndXJhdGlvbiAoJWhYKS4iCgkgICAgICJQcm9iYWJseSBub3QgYSBTTUMgY2hpcFxuIiwKCSAgICAgaW9hZGRyLCBiYXNlX2FkZHJlc3NfcmVnaXN0ZXIgPj4gMyAmIDB4M0UwKTsKI2VuZGlmCiAgICAgIC8qIHdlbGwsIHRoZSBiYXNlIGFkZHJlc3MgcmVnaXN0ZXIgZGlkbid0IG1hdGNoLiAgTXVzdCBub3QgaGF2ZQogICAgICAgKiBiZWVuIGEgU01DIGNoaXAgYWZ0ZXIgYWxsLiAqLwogICAgICByZXR1cm4gLTE7CiAgIH0KCgogICAvKiBjaGVjayBpZiB0aGUgcmV2aXNpb24gcmVnaXN0ZXIgaXMgc29tZXRoaW5nIHRoYXQgSSByZWNvZ25pemUuCiAgICAqIFRoZXNlIG1pZ2h0IG5lZWQgdG8gYmUgYWRkZWQgdG8gbGF0ZXIsIGFzIGZ1dHVyZSByZXZpc2lvbnMKICAgICogY291bGQgYmUgYWRkZWQuICAqLwogICBTTUNfU0VMRUNUX0JBTksoaW9hZGRyLCAzKTsKICAgcmV2aXNpb25fcmVnaXN0ZXIgID0gaW53KGlvYWRkciArIFJFVklTSU9OKTsKICAgaWYgKCFjaGlwX2lkc1socmV2aXNpb25fcmVnaXN0ZXIgPj4gNCkgJiAweEZdKSB7CiAgICAgIC8qIEkgZG9uJ3QgcmVjb2duaXplIHRoaXMgY2hpcCwgc28uLi4gKi8KI2lmZGVmCVNNQzkwMDBfVkVSQk9TRQogICAgICBwcmludGYoIlNNQzkwMDA6IElPICVoWDogVW5yZWNvZ25pemVkIHJldmlzaW9uIHJlZ2lzdGVyOiIKCSAgICAgIiAlaFgsIENvbnRhY3QgYXV0aG9yLlxuIiwgaW9hZGRyLCByZXZpc2lvbl9yZWdpc3Rlcik7CiNlbmRpZgogICAgICByZXR1cm4gLTE7CiAgIH0KCiAgIC8qIGF0IHRoaXMgcG9pbnQgSSdsbCBhc3N1bWUgdGhhdCB0aGUgY2hpcCBpcyBhbiBTTUM5eHh4LgogICAgKiBJdCBtaWdodCBiZSBwcnVkZW50IHRvIGNoZWNrIGEgbGlzdGluZyBvZiBNQUMgYWRkcmVzc2VzCiAgICAqIGFnYWluc3QgdGhlIGhhcmR3YXJlIGFkZHJlc3MsIG9yIGRvIHNvbWUgb3RoZXIgdGVzdHMuICovCiAgIHJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEVUSF9SRVNFVCAtIFJlc2V0IGFkYXB0ZXIKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkIHNtYzkwMDBfcmVzZXQoc3RydWN0IG5pYyAqbmljKQp7CiAgIHNtY19yZXNldChzbWM5MDAwX2Jhc2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRVRIX1RSQU5TTUlUIC0gVHJhbnNtaXQgYSBmcmFtZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBzbWM5MDAwX3RyYW5zbWl0KAoJc3RydWN0IG5pYyAqbmljLAoJY29uc3QgY2hhciAqZCwJCQkvKiBEZXN0aW5hdGlvbiAqLwoJdW5zaWduZWQgaW50IHQsCQkJLyogVHlwZSAqLwoJdW5zaWduZWQgaW50IHMsCQkJLyogc2l6ZSAqLwoJY29uc3QgY2hhciAqcCkJCQkvKiBQYWNrZXQgKi8KewogICB3b3JkIGxlbmd0aDsgLyogcmVhbCwgbGVuZ3RoIGluY2wuIGhlYWRlciAqLwogICB3b3JkIG51bVBhZ2VzOwogICB1bnNpZ25lZCBsb25nIHRpbWVfb3V0OwogICBieXRlCXBhY2tldF9ubzsKICAgd29yZCBzdGF0dXM7CiAgIGludCBpOwoKICAgLyogV2UgZG9udCBwYWQgaGVyZSBzaW5jZSB3ZSBjYW4gaGF2ZSB0aGUgaGFyZHdhcmUgZG9pbmcgaXQgZm9yIHVzICovCiAgIGxlbmd0aCA9IChzICsgRVRIX0hMRU4gKyAxKSZ+MTsKCiAgIC8qIGNvbnZlcnQgdG8gTU1VIHBhZ2VzICovCiAgIG51bVBhZ2VzID0gbGVuZ3RoIC8gMjU2OwoKICAgaWYgKG51bVBhZ2VzID4gNyApIHsKI2lmZGVmCVNNQzkwMDBfVkVSQk9TRQogICAgICBwcmludGYoIlNNQzkwMDA6IEZhciB0b28gYmlnIHBhY2tldCBlcnJvci4gXG4iKTsKI2VuZGlmCiAgICAgIHJldHVybjsKICAgfQoKICAgLyogZG9udCB0cnkgbW9yZSB0aGFuLCBzYXkgMzAgdGltZXMgKi8KICAgZm9yIChpPTA7aTwzMDtpKyspIHsKICAgICAgLyogbm93LCB0cnkgdG8gYWxsb2NhdGUgdGhlIG1lbW9yeSAqLwogICAgICBTTUNfU0VMRUNUX0JBTksoc21jOTAwMF9iYXNlLCAyKTsKICAgICAgX291dHcoTUNfQUxMT0MgfCBudW1QYWdlcywgc21jOTAwMF9iYXNlICsgTU1VX0NNRCk7CgogICAgICBzdGF0dXMgPSAwOwogICAgICAvKiB3YWl0IGZvciB0aGUgbWVtb3J5IGFsbG9jYXRpb24gdG8gZmlubmlzaCAqLwogICAgICBmb3IgKHRpbWVfb3V0ID0gY3VycnRpY2tzKCkgKyA1KlRJQ0tTX1BFUl9TRUM7IGN1cnJ0aWNrcygpIDwgdGltZV9vdXQ7ICkgewoJIHN0YXR1cyA9IGluYihzbWM5MDAwX2Jhc2UgKyBJTlRFUlJVUFQpOwoJIGlmICggc3RhdHVzICYgSU1fQUxMT0NfSU5UICkgewoJICAgIC8qIGFja25vd2xlZGdlIHRoZSBpbnRlcnJ1cHQgKi8KCSAgICBfb3V0YihJTV9BTExPQ19JTlQsIHNtYzkwMDBfYmFzZSArIElOVEVSUlVQVCk7CgkgICAgYnJlYWs7CgkgfQogICAgICB9CgogICAgICBpZiAoKHN0YXR1cyAmIElNX0FMTE9DX0lOVCkgIT0gMCApIHsKCSAvKiBXZSd2ZSBnb3QgdGhlIG1lbW9yeSAqLwoJIGJyZWFrOwogICAgICB9IGVsc2UgewoJIHByaW50ZigiU01DOTAwMDogTWVtb3J5IGFsbG9jYXRpb24gdGltZWQgb3V0LCByZXNldHRpbmcgTU1VLlxuIik7CgkgX291dHcoTUNfUkVTRVQsIHNtYzkwMDBfYmFzZSArIE1NVV9DTUQpOwogICAgICB9CiAgIH0KCiAgIC8qIElmIEkgZ2V0IGhlcmUsIEkgX2tub3dfIHRoZXJlIGlzIGEgcGFja2V0IHNsb3Qgd2FpdGluZyBmb3IgbWUgKi8KICAgcGFja2V0X25vID0gaW5iKHNtYzkwMDBfYmFzZSArIFBOUl9BUlIgKyAxKTsKICAgaWYgKHBhY2tldF9ubyAmIDB4ODApIHsKICAgICAgLyogb3IgaXNuJ3QgdGhlcmU/ICBCQUQgQ0hJUCEgKi8KICAgICAgcHJpbnRmKCJTTUM5MDAwOiBNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQuIFxuIik7CiAgICAgIHJldHVybjsKICAgfQoKICAgLyogd2UgaGF2ZSBhIHBhY2tldCBhZGRyZXNzLCBzbyB0ZWxsIHRoZSBjYXJkIHRvIHVzZSBpdCAqLwogICBfb3V0YihwYWNrZXRfbm8sIHNtYzkwMDBfYmFzZSArIFBOUl9BUlIpOwoKICAgLyogcG9pbnQgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgcGFja2V0ICovCiAgIF9vdXR3KFBUUl9BVVRPSU5DLCBzbWM5MDAwX2Jhc2UgKyBQT0lOVEVSKTsKCiNpZglTTUM5MDAwX0RFQlVHID4gMgogICBwcmludGYoIlRyeWluZyB0byB4bWl0IHBhY2tldCBvZiBsZW5ndGggJWhYXG4iLCBsZW5ndGggKTsKI2VuZGlmCgogICAvKiBzZW5kIHRoZSBwYWNrZXQgbGVuZ3RoICggKzYgZm9yIHN0YXR1cywgbGVuZ3RoIGFuZCBjdGwgYnl0ZSApCiAgICAqIGFuZCB0aGUgc3RhdHVzIHdvcmQgKCBzZXQgdG8gemVyb3MgKSAqLwogICBfb3V0dygwLCBzbWM5MDAwX2Jhc2UgKyBEQVRBXzEgKTsKCiAgIC8qIHNlbmQgdGhlIHBhY2tldCBsZW5ndGggKCArNiBmb3Igc3RhdHVzIHdvcmRzLCBsZW5ndGgsIGFuZCBjdGwpICovCiAgIF9vdXRiKChsZW5ndGgrNikgJiAweEZGLCAgc21jOTAwMF9iYXNlICsgREFUQV8xKTsKICAgX291dGIoKGxlbmd0aCs2KSA+PiA4ICwgICBzbWM5MDAwX2Jhc2UgKyBEQVRBXzEpOwoKICAgLyogV3JpdGUgdGhlIGNvbnRlbnRzIG9mIHRoZSBwYWNrZXQgKi8KCiAgIC8qIFRoZSBldGhlcm5ldCBoZWFkZXIgZmlyc3QuLi4gKi8KICAgb3V0c3coc21jOTAwMF9iYXNlICsgREFUQV8xLCBkLCBFVEhfQUxFTiA+PiAxKTsKICAgb3V0c3coc21jOTAwMF9iYXNlICsgREFUQV8xLCBuaWMtPm5vZGVfYWRkciwgRVRIX0FMRU4gPj4gMSk7CiAgIF9vdXR3KGh0b25zKHQpLCBzbWM5MDAwX2Jhc2UgKyBEQVRBXzEpOwoKICAgLyogLi4uIHRoZSBkYXRhIC4uLiAqLwogICBvdXRzdyhzbWM5MDAwX2Jhc2UgKyBEQVRBXzEgLCBwLCBzID4+IDEpOwoKICAgLyogLi4uIGFuZCB0aGUgbGFzdCBieXRlLCBpZiB0aGVyZSBpcyBvbmUuICAgKi8KICAgaWYgKChzICYgMSkgPT0gMCkgewogICAgICBfb3V0dygwLCBzbWM5MDAwX2Jhc2UgKyBEQVRBXzEpOwogICB9IGVsc2UgewogICAgICBfb3V0YihwW3MtMV0sIHNtYzkwMDBfYmFzZSArIERBVEFfMSk7CiAgICAgIF9vdXRiKDB4MjAsIHNtYzkwMDBfYmFzZSArIERBVEFfMSk7CiAgIH0KCiAgIC8qIGFuZCBsZXQgdGhlIGNoaXBzZXQgZGVhbCB3aXRoIGl0ICovCiAgIF9vdXR3KE1DX0VOUVVFVUUgLCBzbWM5MDAwX2Jhc2UgKyBNTVVfQ01EKTsKCiAgIHN0YXR1cyA9IDA7IHRpbWVfb3V0ID0gY3VycnRpY2tzKCkgKyA1KlRJQ0tTX1BFUl9TRUM7CiAgIGRvIHsKICAgICAgc3RhdHVzID0gaW5iKHNtYzkwMDBfYmFzZSArIElOVEVSUlVQVCk7CgogICAgICBpZiAoKHN0YXR1cyAmIElNX1RYX0lOVCApICE9IDApIHsKCSB3b3JkIHR4X3N0YXR1czsKCgkgLyogYWNrIGludGVycnVwdCAqLwoJIF9vdXRiKElNX1RYX0lOVCwgc21jOTAwMF9iYXNlICsgSU5URVJSVVBUKTsKCgkgcGFja2V0X25vID0gaW53KHNtYzkwMDBfYmFzZSArIEZJRk9fUE9SVFMpOwoJIHBhY2tldF9ubyAmPSAweDdGOwoKCSAvKiBzZWxlY3QgdGhpcyBhcyB0aGUgcGFja2V0IHRvIHJlYWQgZnJvbSAqLwoJIF9vdXRiKCBwYWNrZXRfbm8sIHNtYzkwMDBfYmFzZSArIFBOUl9BUlIgKTsKCgkgLyogcmVhZCB0aGUgZmlyc3Qgd29yZCBmcm9tIHRoaXMgcGFja2V0ICovCgkgX291dHcoIFBUUl9BVVRPSU5DIHwgUFRSX1JFQUQsIHNtYzkwMDBfYmFzZSArIFBPSU5URVIgKTsKCgkgdHhfc3RhdHVzID0gaW53KCBzbWM5MDAwX2Jhc2UgKyBEQVRBXzEgKTsKCgkgaWYgKDAgPT0gKHR4X3N0YXR1cyAmIFRTX1NVQ0NFU1MpKSB7CiNpZmRlZglTTUM5MDAwX1ZFUkJPU0UKCSAgICBwcmludGYoIlNNQzkwMDA6IFRYIEZBSUwgU1RBVFVTOiAlaFggXG4iLCB0eF9zdGF0dXMpOwojZW5kaWYKCSAgICAvKiByZS1lbmFibGUgdHJhbnNtaXQgKi8KCSAgICBTTUNfU0VMRUNUX0JBTksoc21jOTAwMF9iYXNlLCAwKTsKCSAgICBfb3V0dyhpbncoc21jOTAwMF9iYXNlICsgVENSICkgfCBUQ1JfRU5BQkxFLCBzbWM5MDAwX2Jhc2UgKyBUQ1IgKTsKCSB9CgoJIC8qIGtpbGwgdGhlIHBhY2tldCAqLwoJIFNNQ19TRUxFQ1RfQkFOSyhzbWM5MDAwX2Jhc2UsIDIpOwoJIF9vdXR3KE1DX0ZSRUVQS1QsIHNtYzkwMDBfYmFzZSArIE1NVV9DTUQpOwoKCSByZXR1cm47CiAgICAgIH0KICAgfXdoaWxlKGN1cnJ0aWNrcygpIDwgdGltZV9vdXQpOwoKICAgcHJpbnRmKCJTTUM5MDAwOiBXYXJpbmcgVFggdGltZWQgb3V0LCByZXNldHRpbmcgYm9hcmRcbiIpOwogICBzbWNfcmVzZXQoc21jOTAwMF9iYXNlKTsKICAgcmV0dXJuOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRVRIX1BPTEwgLSBXYWl0IGZvciBhIGZyYW1lCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBpbnQgc21jOTAwMF9wb2xsKHN0cnVjdCBuaWMgKm5pYykKewogICBpZighc21jOTAwMF9iYXNlKQogICAgIHJldHVybiAwOwoKICAgU01DX1NFTEVDVF9CQU5LKHNtYzkwMDBfYmFzZSwgMik7CiAgIGlmIChpbncoc21jOTAwMF9iYXNlICsgRklGT19QT1JUUykgJiBGUF9SWEVNUFRZKQogICAgIHJldHVybiAwOwoKICAgLyogIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHBhY2tldCAqLwogICBfb3V0dyhQVFJfUkVBRCB8IFBUUl9SQ1YgfCBQVFJfQVVUT0lOQywgc21jOTAwMF9iYXNlICsgUE9JTlRFUik7CgogICAvKiBGaXJzdCByZWFkIHRoZSBzdGF0dXMgYW5kIGNoZWNrIHRoYXQgd2UncmUgb2sgKi8KICAgaWYgKCEoaW53KHNtYzkwMDBfYmFzZSArIERBVEFfMSkgJiBSU19FUlJPUlMpKSB7CiAgICAgIC8qIE5leHQ6IHJlYWQgdGhlIHBhY2tldCBsZW5ndGggYW5kIG1hc2sgb2ZmIHRoZSB0b3AgYml0cyAqLwogICAgICBuaWMtPnBhY2tldGxlbiA9IChpbncoc21jOTAwMF9iYXNlICsgREFUQV8xKSAmIDB4MDdmZik7CgogICAgICAvKiB0aGUgcGFja2V0IGxlbmd0aCBpbmNsdWRlcyB0aGUgMyBleHRyYSB3b3JkcyAqLwogICAgICBuaWMtPnBhY2tldGxlbiAtPSA2OwojaWYJU01DOTAwMF9ERUJVRyA+IDIKICAgICAgcHJpbnRmKCIgUmVhZGluZyAlZCB3b3JkcyAoYW5kICVkIGJ5dGUocykpXG4iLAoJICAgICAgIChuaWMtPnBhY2tldGxlbiA+PiAxKSwgbmljLT5wYWNrZXRsZW4gJiAxKTsKI2VuZGlmCiAgICAgIC8qIHJlYWQgdGhlIHBhY2tldCAoYW5kIHRoZSBsYXN0ICJleHRyYSIgd29yZCkgKi8KICAgICAgaW5zdyhzbWM5MDAwX2Jhc2UgKyBEQVRBXzEsIG5pYy0+cGFja2V0LCAobmljLT5wYWNrZXRsZW4rMikgPj4gMSk7CiAgICAgIC8qIGlzIHRoZXJlIGFuIG9kZCBsYXN0IGJ5dGUgPyAqLwogICAgICBpZiAobmljLT5wYWNrZXRbbmljLT5wYWNrZXRsZW4rMV0gJiAweDIwKQoJIG5pYy0+cGFja2V0bGVuKys7CgogICAgICAvKiAgZXJyb3Igb3IgZ29vZCwgdGVsbCB0aGUgY2FyZCB0byBnZXQgcmlkIG9mIHRoaXMgcGFja2V0ICovCiAgICAgIF9vdXR3KE1DX1JFTEVBU0UsIHNtYzkwMDBfYmFzZSArIE1NVV9DTUQpOwogICAgICByZXR1cm4gMTsKICAgfQoKICAgcHJpbnRmKCJTTUM5MDAwOiBSWCBlcnJvclxuIik7CiAgIC8qICBlcnJvciBvciBnb29kLCB0ZWxsIHRoZSBjYXJkIHRvIGdldCByaWQgb2YgdGhpcyBwYWNrZXQgKi8KICAgX291dHcoTUNfUkVMRUFTRSwgc21jOTAwMF9iYXNlICsgTU1VX0NNRCk7CiAgIHJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBzbWM5MDAwX2Rpc2FibGUoc3RydWN0IG5pYyAqbmljKQp7CiAgIGlmKCFzbWM5MDAwX2Jhc2UpCiAgICAgcmV0dXJuOwoKICAgLyogbm8gbW9yZSBpbnRlcnJ1cHRzIGZvciBtZSAqLwogICBTTUNfU0VMRUNUX0JBTksoc21jOTAwMF9iYXNlLCAyKTsKICAgX291dGIoIDAsIHNtYzkwMDBfYmFzZSArIElOVF9NQVNLKTsKCiAgIC8qIGFuZCB0ZWxsIHRoZSBjYXJkIHRvIHN0YXkgYXdheSBmcm9tIHRoYXQgbmFzdHkgb3V0c2lkZSB3b3JsZCAqLwogICBTTUNfU0VMRUNUX0JBTksoc21jOTAwMF9iYXNlLCAwKTsKICAgX291dGIoIFJDUl9DTEVBUiwgc21jOTAwMF9iYXNlICsgUkNSICk7CiAgIF9vdXRiKCBUQ1JfQ0xFQVIsIHNtYzkwMDBfYmFzZSArIFRDUiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRVRIX1BST0JFIC0gTG9vayBmb3IgYW4gYWRhcHRlcgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RydWN0IG5pYyAqc21jOTAwMF9wcm9iZShzdHJ1Y3QgbmljICpuaWMsIHVuc2lnbmVkIHNob3J0ICpwcm9iZV9hZGRycykKewogICB1bnNpZ25lZCBzaG9ydCAgIHJldmlzaW9uOwogICBpbnQJICAgICAgICAgICAgbWVtb3J5OwogICBpbnQgICAgICAgICAgICAgIG1lZGlhOwogICBjb25zdCBjaGFyICoJICAgIHZlcnNpb25fc3RyaW5nOwogICBjb25zdCBjaGFyICoJICAgIGlmX3N0cmluZzsKICAgaW50ICAgICAgICAgICAgICBpOwoKICAgLyoKICAgICogdGhlIFNNQzkwMDAgY2FuIGJlIGF0IGFueSBvZiB0aGUgZm9sbG93aW5nIHBvcnQgYWRkcmVzc2VzLiAgVG8gY2hhbmdlLAogICAgKiBmb3IgYSBzbGlnaHRseSBkaWZmZXJlbnQgY2FyZCwgeW91IGNhbiBhZGQgaXQgdG8gdGhlIGFycmF5LiAgS2VlcCBpbgogICAgKiBtaW5kIHRoYXQgdGhlIGFycmF5IG11c3QgZW5kIGluIHplcm8uCiAgICAqLwogICBzdGF0aWMgdW5zaWduZWQgc2hvcnQgcG9ydGxpc3RbXSA9IHsKI2lmZGVmCVNNQzkwMDBfU0NBTgogICAgICBTTUM5MDAwX1NDQU4sCiNlbHNlCiAgICAgIDB4MjAwLCAweDIyMCwgMHgyNDAsIDB4MjYwLCAweDI4MCwgMHgyQTAsIDB4MkMwLCAweDJFMCwKICAgICAgMHgzMDAsIDB4MzIwLCAweDM0MCwgMHgzNjAsIDB4MzgwLCAweDNBMCwgMHgzQzAsIDB4M0UwLAojZW5kaWYKICAgICAgMCB9OwoKICAgcHJpbnRmKCJcblNNQzkwMDAgJXNcbiIsIHNtYzkwMDBfdmVyc2lvbik7CiNpZmRlZglTTUM5MDAwX1ZFUkJPU0UKICAgcHJpbnRmKCJDb3B5cmlnaHQgKEMpIDE5OTggRGFuaWVsIEVuZ3N0clx4OTRtXG4iKTsKICAgcHJpbnRmKCJDb3B5cmlnaHQgKEMpIDE5OTYgRXJpYyBTdGFobG1hblxuIik7CiNlbmRpZgogICAvKiBpZiBubyBhZGRyZXNzZXMgc3VwcGxpZWQsIGZhbGwgYmFjayBvbiBkZWZhdWx0cyAqLwogICBpZiAocHJvYmVfYWRkcnMgPT0gMCB8fCBwcm9iZV9hZGRyc1swXSA9PSAwKQogICAgIHByb2JlX2FkZHJzID0gcG9ydGxpc3Q7CgogICAvKiBjaGVjayBldmVyeSBldGhlcm5ldCBhZGRyZXNzICovCiAgIGZvciAoaSA9IDA7IHByb2JlX2FkZHJzW2ldOyBpKyspIHsKICAgICAgLyogY2hlY2sgdGhpcyBzcGVjaWZpYyBhZGRyZXNzICovCiAgICAgIGlmIChzbWNfcHJvYmUocHJvYmVfYWRkcnNbaV0pID09IDApCglzbWM5MDAwX2Jhc2UgPSBwcm9iZV9hZGRyc1tpXTsKICAgfQoKICAgLyogY291bGRuJ3QgZmluZCBhbnl0aGluZyAqLwogICBpZigwID09IHNtYzkwMDBfYmFzZSkKICAgICBnb3RvIG91dDsKCiAgIC8qCiAgICAqIEdldCB0aGUgTUFDIGFkZHJlc3MgKCBiYW5rIDEsIHJlZ3MgNCAtIDkgKQogICAgKi8KICAgU01DX1NFTEVDVF9CQU5LKHNtYzkwMDBfYmFzZSwgMSk7CiAgIGZvciAoIGkgPSAwOyBpIDwgNjsgaSArPSAyICkgewogICAgICB3b3JkIGFkZHJlc3M7CgogICAgICBhZGRyZXNzID0gaW53KHNtYzkwMDBfYmFzZSArIEFERFIwICsgaSk7CiAgICAgIG5pYy0+bm9kZV9hZGRyW2krMV0gPSBhZGRyZXNzID4+IDg7CiAgICAgIG5pYy0+bm9kZV9hZGRyW2ldID0gYWRkcmVzcyAmIDB4RkY7CiAgIH0KCgogICAvKiBnZXQgdGhlIG1lbW9yeSBpbmZvcm1hdGlvbiAqLwogICBTTUNfU0VMRUNUX0JBTksoc21jOTAwMF9iYXNlLCAwKTsKICAgbWVtb3J5ID0gKCBpbncoc21jOTAwMF9iYXNlICsgTUNSKSA+PiA5ICkgICYgMHg3OyAgLyogbXVsdGlwbGllciAqLwogICBtZW1vcnkgKj0gMjU2ICogKGludyhzbWM5MDAwX2Jhc2UgKyBNSVIpICYgMHhGRik7CgogICAvKgogICAgKiBOb3csIEkgd2FudCB0byBmaW5kIG91dCBtb3JlIGFib3V0IHRoZSBjaGlwLiAgVGhpcyBpcyBzb3J0IG9mCiAgICAqIHJlZHVuZGFudCwgYnV0IGl0J3MgY2xlYW5lciB0byBoYXZlIGl0IGluIGJvdGgsIHJhdGhlciB0aGFuIGhhdmluZwogICAgKiBvbmUgVkVSWSBsb25nIHByb2JlIHByb2NlZHVyZS4KICAgICovCiAgIFNNQ19TRUxFQ1RfQkFOSyhzbWM5MDAwX2Jhc2UsIDMpOwogICByZXZpc2lvbiAgPSBpbncoc21jOTAwMF9iYXNlICsgUkVWSVNJT04pOwogICB2ZXJzaW9uX3N0cmluZyA9IGNoaXBfaWRzWyhyZXZpc2lvbiA+PiA0KSAmIDB4Rl07CgogICBpZiAoKChyZXZpc2lvbiAmIDB4RjApID4+IDQgPT0gQ0hJUF85MTk2KSAmJgogICAgICAgKChyZXZpc2lvbiAmIDB4MEYpID49IFJFVl85MTk2KSkgewogICAgICAvKiBUaGlzIGlzIGEgOTFjOTYuICdjOTYgaGFzIHRoZSBzYW1lIGNoaXAgaWQgYXMgJ2M5NCAoNCkgYnV0CiAgICAgICAqIGEgcmV2aXNpb24gc3RhcnRpbmcgYXQgNiAqLwogICAgICB2ZXJzaW9uX3N0cmluZyA9IHNtYzkxYzk2X2lkOwogICB9CgogICBpZiAoICF2ZXJzaW9uX3N0cmluZyApIHsKICAgICAgLyogSSBzaG91bGRuJ3QgZ2V0IGhlcmUgYmVjYXVzZSB0aGlzIGNhbGwgd2FzIGRvbmUgYmVmb3JlLi4uLiAqLwogICAgICBnb3RvIG91dDsKICAgfQoKICAgLyogaXMgaXQgdXNpbmcgQVVJIG9yIDEwQmFzZVQgPyAqLwogICBTTUNfU0VMRUNUX0JBTksoc21jOTAwMF9iYXNlLCAxKTsKICAgaWYgKGludyhzbWM5MDAwX2Jhc2UgKyBDT05GSUcpICYgQ0ZHX0FVSV9TRUxFQ1QpCiAgICAgbWVkaWEgPSAyOwogICBlbHNlCiAgICAgbWVkaWEgPSAxOwoKICAgaWZfc3RyaW5nID0gaW50ZXJmYWNlc1ttZWRpYSAtIDFdOwoKICAgLyogbm93LCByZXNldCB0aGUgY2hpcCwgYW5kIHB1dCBpdCBpbnRvIGEga25vd24gc3RhdGUgKi8KICAgc21jX3Jlc2V0KHNtYzkwMDBfYmFzZSk7CgogICBwcmludGYoIiVzIHJldjolZCBJL08gcG9ydDolaFggSW50ZXJmYWNlOiVzIFJBTTolZCBieXRlcyBcbiIsCgkgIHZlcnNpb25fc3RyaW5nLCByZXZpc2lvbiAmIDB4RiwKCSAgc21jOTAwMF9iYXNlLCBpZl9zdHJpbmcsIG1lbW9yeSApOwogICAvKgogICAgKiBQcmludCB0aGUgRXRoZXJuZXQgYWRkcmVzcwogICAgKi8KICAgcHJpbnRmKCJFdGhlcm5ldCBNQUMgYWRkcmVzczogJSFcbiIsIG5pYy0+bm9kZV9hZGRyKTsKCiAgIFNNQ19TRUxFQ1RfQkFOSyhzbWM5MDAwX2Jhc2UsIDApOwoKICAgLyogc2VlIHRoZSBoZWFkZXIgZmlsZSBmb3Igb3B0aW9ucyBpbiBUQ1IvUkNSIE5PUk1BTCovCiAgIF9vdXR3KFRDUl9OT1JNQUwsIHNtYzkwMDBfYmFzZSArIFRDUik7CiAgIF9vdXR3KFJDUl9OT1JNQUwsIHNtYzkwMDBfYmFzZSArIFJDUik7CgogICAvKiBTZWxlY3Qgd2hpY2ggaW50ZXJmYWNlIHRvIHVzZSAqLwogICBTTUNfU0VMRUNUX0JBTksoc21jOTAwMF9iYXNlLCAxKTsKICAgaWYgKCBtZWRpYSA9PSAxICkgewogICAgICBfb3V0dyggaW53KCBzbWM5MDAwX2Jhc2UgKyBDT05GSUcgKSAmIH5DRkdfQVVJX1NFTEVDVCwKCSAgIHNtYzkwMDBfYmFzZSArIENPTkZJRyApOwogICB9CiAgIGVsc2UgaWYgKCBtZWRpYSA9PSAyICkgewogICAgICBfb3V0dyggaW53KCBzbWM5MDAwX2Jhc2UgKyBDT05GSUcgKSB8IENGR19BVUlfU0VMRUNULAoJICAgc21jOTAwMF9iYXNlICsgQ09ORklHICk7CiAgIH0KCiAgIG5pYy0+cmVzZXQgPSBzbWM5MDAwX3Jlc2V0OwogICBuaWMtPnBvbGwgPSBzbWM5MDAwX3BvbGw7CiAgIG5pYy0+dHJhbnNtaXQgPSBzbWM5MDAwX3RyYW5zbWl0OwogICBuaWMtPmRpc2FibGUgPSBzbWM5MDAwX2Rpc2FibGU7CgoKICAgcmV0dXJuIG5pYzsKCm91dDoKI2lmZGVmCVNNQzkwMDBfVkVSQk9TRQogICBwcmludGYoIk5vIFNNQzkwMDAgYWRhcHRlcnMgZm91bmRcbiIpOwojZW5kaWYKICAgc21jOTAwMF9iYXNlID0gMDsKCiAgIHJldHVybiAoMCk7Cn0KCgoK