LyogRm9sZCBhIGNvbnN0YW50IHN1Yi10cmVlIGludG8gYSBzaW5nbGUgbm9kZSBmb3IgQy1jb21waWxlcgogICBDb3B5cmlnaHQgKEMpIDE5ODcsIDE5ODgsIDE5OTIsIDE5OTMsIDE5OTQsIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTksCiAgIDIwMDAsIDIwMDEsIDIwMDIsIDIwMDMsIDIwMDQgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCgpUaGlzIGZpbGUgaXMgcGFydCBvZiBHQ0MuCgpHQ0MgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdCB1bmRlcgp0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZQpTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlcgp2ZXJzaW9uLgoKR0NDIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUIEFOWQpXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgpGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKZm9yIG1vcmUgZGV0YWlscy4KCllvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCmFsb25nIHdpdGggR0NDOyBzZWUgdGhlIGZpbGUgQ09QWUlORy4gIElmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUKU29mdHdhcmUgRm91bmRhdGlvbiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BCjAyMTExLTEzMDcsIFVTQS4gICovCgovKkBAIFRoaXMgZmlsZSBzaG91bGQgYmUgcmV3cml0dGVuIHRvIHVzZSBhbiBhcmJpdHJhcnkgcHJlY2lzaW9uCiAgQEAgcmVwcmVzZW50YXRpb24gZm9yICJzdHJ1Y3QgdHJlZV9pbnRfY3N0IiBhbmQgInN0cnVjdCB0cmVlX3JlYWxfY3N0Ii4KICBAQCBQZXJoYXBzIHRoZSByb3V0aW5lcyBjb3VsZCBhbHNvIGJlIHVzZWQgZm9yIGJjL2RjLCBhbmQgbWFkZSBhIGxpYi4KICBAQCBUaGUgcm91dGluZXMgdGhhdCB0cmFuc2xhdGUgZnJvbSB0aGUgYXAgcmVwIHNob3VsZAogIEBAIHdhcm4gaWYgcHJlY2lzaW9uIGV0LiBhbC4gaXMgbG9zdC4KICBAQCBUaGlzIHdvdWxkIGFsc28gbWFrZSBsaWZlIGVhc2llciB3aGVuIHRoaXMgdGVjaG5vbG9neSBpcyB1c2VkCiAgQEAgZm9yIGNyb3NzLWNvbXBpbGVycy4gICovCgovKiBUaGUgZW50cnkgcG9pbnRzIGluIHRoaXMgZmlsZSBhcmUgZm9sZCwgc2l6ZV9pbnRfd2lkZSwgc2l6ZV9iaW5vcAogICBhbmQgZm9yY2VfZml0X3R5cGUuCgogICBmb2xkIHRha2VzIGEgdHJlZSBhcyBhcmd1bWVudCBhbmQgcmV0dXJucyBhIHNpbXBsaWZpZWQgdHJlZS4KCiAgIHNpemVfYmlub3AgdGFrZXMgYSB0cmVlIGNvZGUgZm9yIGFuIGFyaXRobWV0aWMgb3BlcmF0aW9uCiAgIGFuZCB0d28gb3BlcmFuZHMgdGhhdCBhcmUgdHJlZXMsIGFuZCBwcm9kdWNlcyBhIHRyZWUgZm9yIHRoZQogICByZXN1bHQsIGFzc3VtaW5nIHRoZSB0eXBlIGNvbWVzIGZyb20gYHNpemV0eXBlJy4KCiAgIHNpemVfaW50IHRha2VzIGFuIGludGVnZXIgdmFsdWUsIGFuZCBjcmVhdGVzIGEgdHJlZSBjb25zdGFudAogICB3aXRoIHR5cGUgZnJvbSBgc2l6ZXR5cGUnLgoKICAgZm9yY2VfZml0X3R5cGUgdGFrZXMgYSBjb25zdGFudCBhbmQgcHJpb3Igb3ZlcmZsb3cgaW5kaWNhdG9yLCBhbmQKICAgZm9yY2VzIHRoZSB2YWx1ZSB0byBmaXQgdGhlIHR5cGUuICBJdCByZXR1cm5zIGFuIG92ZXJmbG93IGluZGljYXRvci4gICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJzeXN0ZW0uaCIKI2luY2x1ZGUgImNvcmV0eXBlcy5oIgojaW5jbHVkZSAidG0uaCIKI2luY2x1ZGUgImZsYWdzLmgiCiNpbmNsdWRlICJ0cmVlLmgiCiNpbmNsdWRlICJyZWFsLmgiCiNpbmNsdWRlICJydGwuaCIKI2luY2x1ZGUgImV4cHIuaCIKI2luY2x1ZGUgInRtX3AuaCIKI2luY2x1ZGUgInRvcGxldi5oIgojaW5jbHVkZSAiZ2djLmgiCiNpbmNsdWRlICJoYXNodGFiLmgiCiNpbmNsdWRlICJsYW5naG9va3MuaCIKI2luY2x1ZGUgIm1kNS5oIgoKc3RhdGljIHZvaWQgZW5jb2RlIChIT1NUX1dJREVfSU5UICosIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQsIEhPU1RfV0lERV9JTlQpOwpzdGF0aWMgdm9pZCBkZWNvZGUgKEhPU1RfV0lERV9JTlQgKiwgdW5zaWduZWQgSE9TVF9XSURFX0lOVCAqLCBIT1NUX1dJREVfSU5UICopOwpzdGF0aWMgYm9vbCBuZWdhdGVfbWF0aGZuX3AgKGVudW0gYnVpbHRfaW5fZnVuY3Rpb24pOwpzdGF0aWMgYm9vbCBuZWdhdGVfZXhwcl9wICh0cmVlKTsKc3RhdGljIHRyZWUgbmVnYXRlX2V4cHIgKHRyZWUpOwpzdGF0aWMgdHJlZSBzcGxpdF90cmVlICh0cmVlLCBlbnVtIHRyZWVfY29kZSwgdHJlZSAqLCB0cmVlICosIHRyZWUgKiwgaW50KTsKc3RhdGljIHRyZWUgYXNzb2NpYXRlX3RyZWVzICh0cmVlLCB0cmVlLCBlbnVtIHRyZWVfY29kZSwgdHJlZSk7CnN0YXRpYyB0cmVlIGludF9jb25zdF9iaW5vcCAoZW51bSB0cmVlX2NvZGUsIHRyZWUsIHRyZWUsIGludCk7CnN0YXRpYyB0cmVlIGNvbnN0X2Jpbm9wIChlbnVtIHRyZWVfY29kZSwgdHJlZSwgdHJlZSwgaW50KTsKc3RhdGljIGhhc2h2YWxfdCBzaXplX2h0YWJfaGFzaCAoY29uc3Qgdm9pZCAqKTsKc3RhdGljIGludCBzaXplX2h0YWJfZXEgKGNvbnN0IHZvaWQgKiwgY29uc3Qgdm9pZCAqKTsKc3RhdGljIHRyZWUgZm9sZF9jb252ZXJ0X2NvbnN0IChlbnVtIHRyZWVfY29kZSwgdHJlZSwgdHJlZSk7CnN0YXRpYyB0cmVlIGZvbGRfY29udmVydCAodHJlZSwgdHJlZSk7CnN0YXRpYyBlbnVtIHRyZWVfY29kZSBpbnZlcnRfdHJlZV9jb21wYXJpc29uIChlbnVtIHRyZWVfY29kZSk7CnN0YXRpYyBlbnVtIHRyZWVfY29kZSBzd2FwX3RyZWVfY29tcGFyaXNvbiAoZW51bSB0cmVlX2NvZGUpOwpzdGF0aWMgaW50IGNvbXBhcmlzb25fdG9fY29tcGNvZGUgKGVudW0gdHJlZV9jb2RlKTsKc3RhdGljIGVudW0gdHJlZV9jb2RlIGNvbXBjb2RlX3RvX2NvbXBhcmlzb24gKGludCk7CnN0YXRpYyBpbnQgdHJ1dGhfdmFsdWVfcCAoZW51bSB0cmVlX2NvZGUpOwpzdGF0aWMgaW50IG9wZXJhbmRfZXF1YWxfZm9yX2NvbXBhcmlzb25fcCAodHJlZSwgdHJlZSwgdHJlZSk7CnN0YXRpYyBpbnQgdHdvdmFsX2NvbXBhcmlzb25fcCAodHJlZSwgdHJlZSAqLCB0cmVlICosIGludCAqKTsKc3RhdGljIHRyZWUgZXZhbF9zdWJzdCAodHJlZSwgdHJlZSwgdHJlZSwgdHJlZSwgdHJlZSk7CnN0YXRpYyB0cmVlIHBlZGFudGljX29taXRfb25lX29wZXJhbmQgKHRyZWUsIHRyZWUsIHRyZWUpOwpzdGF0aWMgdHJlZSBkaXN0cmlidXRlX2JpdF9leHByIChlbnVtIHRyZWVfY29kZSwgdHJlZSwgdHJlZSwgdHJlZSk7CnN0YXRpYyB0cmVlIG1ha2VfYml0X2ZpZWxkX3JlZiAodHJlZSwgdHJlZSwgaW50LCBpbnQsIGludCk7CnN0YXRpYyB0cmVlIG9wdGltaXplX2JpdF9maWVsZF9jb21wYXJlIChlbnVtIHRyZWVfY29kZSwgdHJlZSwgdHJlZSwgdHJlZSk7CnN0YXRpYyB0cmVlIGRlY29kZV9maWVsZF9yZWZlcmVuY2UgKHRyZWUsIEhPU1RfV0lERV9JTlQgKiwgSE9TVF9XSURFX0lOVCAqLAoJCQkJICAgIGVudW0gbWFjaGluZV9tb2RlICosIGludCAqLCBpbnQgKiwKCQkJCSAgICB0cmVlICosIHRyZWUgKik7CnN0YXRpYyBpbnQgYWxsX29uZXNfbWFza19wICh0cmVlLCBpbnQpOwpzdGF0aWMgdHJlZSBzaWduX2JpdF9wICh0cmVlLCB0cmVlKTsKc3RhdGljIGludCBzaW1wbGVfb3BlcmFuZF9wICh0cmVlKTsKc3RhdGljIHRyZWUgcmFuZ2VfYmlub3AgKGVudW0gdHJlZV9jb2RlLCB0cmVlLCB0cmVlLCBpbnQsIHRyZWUsIGludCk7CnN0YXRpYyB0cmVlIG1ha2VfcmFuZ2UgKHRyZWUsIGludCAqLCB0cmVlICosIHRyZWUgKik7CnN0YXRpYyB0cmVlIGJ1aWxkX3JhbmdlX2NoZWNrICh0cmVlLCB0cmVlLCBpbnQsIHRyZWUsIHRyZWUpOwpzdGF0aWMgaW50IG1lcmdlX3JhbmdlcyAoaW50ICosIHRyZWUgKiwgdHJlZSAqLCBpbnQsIHRyZWUsIHRyZWUsIGludCwgdHJlZSwKCQkJIHRyZWUpOwpzdGF0aWMgdHJlZSBmb2xkX3JhbmdlX3Rlc3QgKHRyZWUpOwpzdGF0aWMgdHJlZSB1bmV4dGVuZCAodHJlZSwgaW50LCBpbnQsIHRyZWUpOwpzdGF0aWMgdHJlZSBmb2xkX3RydXRob3AgKGVudW0gdHJlZV9jb2RlLCB0cmVlLCB0cmVlLCB0cmVlKTsKc3RhdGljIHRyZWUgb3B0aW1pemVfbWlubWF4X2NvbXBhcmlzb24gKHRyZWUpOwpzdGF0aWMgdHJlZSBleHRyYWN0X211bGRpdiAodHJlZSwgdHJlZSwgZW51bSB0cmVlX2NvZGUsIHRyZWUpOwpzdGF0aWMgdHJlZSBleHRyYWN0X211bGRpdl8xICh0cmVlLCB0cmVlLCBlbnVtIHRyZWVfY29kZSwgdHJlZSk7CnN0YXRpYyB0cmVlIHN0cmlwX2NvbXBvdW5kX2V4cHIgKHRyZWUsIHRyZWUpOwpzdGF0aWMgaW50IG11bHRpcGxlX29mX3AgKHRyZWUsIHRyZWUsIHRyZWUpOwpzdGF0aWMgdHJlZSBjb25zdGFudF9ib29sZWFuX25vZGUgKGludCwgdHJlZSk7CnN0YXRpYyBpbnQgY291bnRfY29uZCAodHJlZSwgaW50KTsKc3RhdGljIHRyZWUgZm9sZF9iaW5hcnlfb3Bfd2l0aF9jb25kaXRpb25hbF9hcmcgKGVudW0gdHJlZV9jb2RlLCB0cmVlLCB0cmVlLAoJCQkJCQkgdHJlZSwgaW50KTsKc3RhdGljIGJvb2wgZm9sZF9yZWFsX3plcm9fYWRkaXRpb25fcCAodHJlZSwgdHJlZSwgaW50KTsKc3RhdGljIHRyZWUgZm9sZF9tYXRoZm5fY29tcGFyZSAoZW51bSBidWlsdF9pbl9mdW5jdGlvbiwgZW51bSB0cmVlX2NvZGUsCgkJCQkgdHJlZSwgdHJlZSwgdHJlZSk7CnN0YXRpYyB0cmVlIGZvbGRfaW5mX2NvbXBhcmUgKGVudW0gdHJlZV9jb2RlLCB0cmVlLCB0cmVlLCB0cmVlKTsKc3RhdGljIGJvb2wgcmVvcmRlcl9vcGVyYW5kc19wICh0cmVlLCB0cmVlKTsKc3RhdGljIGJvb2wgdHJlZV9zd2FwX29wZXJhbmRzX3AgKHRyZWUsIHRyZWUsIGJvb2wpOwoKLyogVGhlIGZvbGxvd2luZyBjb25zdGFudHMgcmVwcmVzZW50IGEgYml0IGJhc2VkIGVuY29kaW5nIG9mIEdDQydzCiAgIGNvbXBhcmlzb24gb3BlcmF0b3JzLiAgVGhpcyBlbmNvZGluZyBzaW1wbGlmaWVzIHRyYW5zZm9ybWF0aW9ucwogICBvbiByZWxhdGlvbmFsIGNvbXBhcmlzb24gb3BlcmF0b3JzLCBzdWNoIGFzIEFORCBhbmQgT1IuICAqLwojZGVmaW5lIENPTVBDT0RFX0ZBTFNFICAgMAojZGVmaW5lIENPTVBDT0RFX0xUICAgICAgMQojZGVmaW5lIENPTVBDT0RFX0VRICAgICAgMgojZGVmaW5lIENPTVBDT0RFX0xFICAgICAgMwojZGVmaW5lIENPTVBDT0RFX0dUICAgICAgNAojZGVmaW5lIENPTVBDT0RFX05FICAgICAgNQojZGVmaW5lIENPTVBDT0RFX0dFICAgICAgNgojZGVmaW5lIENPTVBDT0RFX1RSVUUgICAgNwoKLyogV2Uga25vdyB0aGF0IEExICsgQjEgPSBTVU0xLCB1c2luZyAyJ3MgY29tcGxlbWVudCBhcml0aG1ldGljIGFuZCBpZ25vcmluZwogICBvdmVyZmxvdy4gIFN1cHBvc2UgQSwgQiBhbmQgU1VNIGhhdmUgdGhlIHNhbWUgcmVzcGVjdGl2ZSBzaWducyBhcyBBMSwgQjEsCiAgIGFuZCBTVU0xLiAgVGhlbiB0aGlzIHlpZWxkcyBub256ZXJvIGlmIG92ZXJmbG93IG9jY3VycmVkIGR1cmluZyB0aGUKICAgYWRkaXRpb24uCgogICBPdmVyZmxvdyBvY2N1cnMgaWYgQSBhbmQgQiBoYXZlIHRoZSBzYW1lIHNpZ24sIGJ1dCBBIGFuZCBTVU0gZGlmZmVyIGluCiAgIHNpZ24uICBVc2UgYF4nIHRvIHRlc3Qgd2hldGhlciBzaWducyBkaWZmZXIsIGFuZCBgPCAwJyB0byBpc29sYXRlIHRoZQogICBzaWduLiAgKi8KI2RlZmluZSBPVkVSRkxPV19TVU1fU0lHTihhLCBiLCBzdW0pICgofigoYSkgXiAoYikpICYgKChhKSBeIChzdW0pKSkgPCAwKQoMCi8qIFRvIGRvIGNvbnN0YW50IGZvbGRpbmcgb24gSU5URUdFUl9DU1Qgbm9kZXMgcmVxdWlyZXMgdHdvLXdvcmQgYXJpdGhtZXRpYy4KICAgV2UgZG8gdGhhdCBieSByZXByZXNlbnRpbmcgdGhlIHR3by13b3JkIGludGVnZXIgaW4gNCB3b3Jkcywgd2l0aCBvbmx5CiAgIEhPU1RfQklUU19QRVJfV0lERV9JTlQgLyAyIGJpdHMgc3RvcmVkIGluIGVhY2ggd29yZCwgYXMgYSBwb3NpdGl2ZQogICBudW1iZXIuICBUaGUgdmFsdWUgb2YgdGhlIHdvcmQgaXMgTE9XUEFSVCArIEhJR0hQQVJUICogQkFTRS4gICovCgojZGVmaW5lIExPV1BBUlQoeCkgXAogICgoeCkgJiAoKCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSAxIDw8IChIT1NUX0JJVFNfUEVSX1dJREVfSU5UIC8gMikpIC0gMSkpCiNkZWZpbmUgSElHSFBBUlQoeCkgXAogICgodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgKHgpID4+IEhPU1RfQklUU19QRVJfV0lERV9JTlQgLyAyKQojZGVmaW5lIEJBU0UgKCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSAxIDw8IEhPU1RfQklUU19QRVJfV0lERV9JTlQgLyAyKQoKLyogVW5wYWNrIGEgdHdvLXdvcmQgaW50ZWdlciBpbnRvIDQgd29yZHMuCiAgIExPVyBhbmQgSEkgYXJlIHRoZSBpbnRlZ2VyLCBhcyB0d28gYEhPU1RfV0lERV9JTlQnIHBpZWNlcy4KICAgV09SRFMgcG9pbnRzIHRvIHRoZSBhcnJheSBvZiBIT1NUX1dJREVfSU5Ucy4gICovCgpzdGF0aWMgdm9pZAplbmNvZGUgKEhPU1RfV0lERV9JTlQgKndvcmRzLCB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGxvdywgSE9TVF9XSURFX0lOVCBoaSkKewogIHdvcmRzWzBdID0gTE9XUEFSVCAobG93KTsKICB3b3Jkc1sxXSA9IEhJR0hQQVJUIChsb3cpOwogIHdvcmRzWzJdID0gTE9XUEFSVCAoaGkpOwogIHdvcmRzWzNdID0gSElHSFBBUlQgKGhpKTsKfQoKLyogUGFjayBhbiBhcnJheSBvZiA0IHdvcmRzIGludG8gYSB0d28td29yZCBpbnRlZ2VyLgogICBXT1JEUyBwb2ludHMgdG8gdGhlIGFycmF5IG9mIHdvcmRzLgogICBUaGUgaW50ZWdlciBpcyBzdG9yZWQgaW50byAqTE9XIGFuZCAqSEkgYXMgdHdvIGBIT1NUX1dJREVfSU5UJyBwaWVjZXMuICAqLwoKc3RhdGljIHZvaWQKZGVjb2RlIChIT1NUX1dJREVfSU5UICp3b3JkcywgdW5zaWduZWQgSE9TVF9XSURFX0lOVCAqbG93LAoJSE9TVF9XSURFX0lOVCAqaGkpCnsKICAqbG93ID0gd29yZHNbMF0gKyB3b3Jkc1sxXSAqIEJBU0U7CiAgKmhpID0gd29yZHNbMl0gKyB3b3Jkc1szXSAqIEJBU0U7Cn0KDAovKiBNYWtlIHRoZSBpbnRlZ2VyIGNvbnN0YW50IFQgdmFsaWQgZm9yIGl0cyB0eXBlIGJ5IHNldHRpbmcgdG8gMCBvciAxIGFsbAogICB0aGUgYml0cyBpbiB0aGUgY29uc3RhbnQgdGhhdCBkb24ndCBiZWxvbmcgaW4gdGhlIHR5cGUuCgogICBSZXR1cm4gMSBpZiBhIHNpZ25lZCBvdmVyZmxvdyBvY2N1cnMsIDAgb3RoZXJ3aXNlLiAgSWYgT1ZFUkZMT1cgaXMKICAgbm9uemVybywgYSBzaWduZWQgb3ZlcmZsb3cgaGFzIGFscmVhZHkgb2NjdXJyZWQgaW4gY2FsY3VsYXRpbmcgVCwgc28KICAgcHJvcGFnYXRlIGl0LiAgKi8KCmludApmb3JjZV9maXRfdHlwZSAodHJlZSB0LCBpbnQgb3ZlcmZsb3cpCnsKICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGxvdzsKICBIT1NUX1dJREVfSU5UIGhpZ2g7CiAgdW5zaWduZWQgaW50IHByZWM7CgogIGlmIChUUkVFX0NPREUgKHQpID09IFJFQUxfQ1NUKQogICAgewogICAgICAvKiA/Pz8gVXNlZCB0byBjaGVjayBmb3Igb3ZlcmZsb3cgaGVyZSB2aWEgQ0hFQ0tfRkxPQVRfVFlQRS4KCSBDb25zaWRlciBkb2luZyBpdCB2aWEgcmVhbF9jb252ZXJ0IG5vdy4gICovCiAgICAgIHJldHVybiBvdmVyZmxvdzsKICAgIH0KCiAgZWxzZSBpZiAoVFJFRV9DT0RFICh0KSAhPSBJTlRFR0VSX0NTVCkKICAgIHJldHVybiBvdmVyZmxvdzsKCiAgbG93ID0gVFJFRV9JTlRfQ1NUX0xPVyAodCk7CiAgaGlnaCA9IFRSRUVfSU5UX0NTVF9ISUdIICh0KTsKCiAgaWYgKFBPSU5URVJfVFlQRV9QIChUUkVFX1RZUEUgKHQpKQogICAgICB8fCBUUkVFX0NPREUgKFRSRUVfVFlQRSAodCkpID09IE9GRlNFVF9UWVBFKQogICAgcHJlYyA9IFBPSU5URVJfU0laRTsKICBlbHNlCiAgICBwcmVjID0gVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAodCkpOwoKICAvKiBGaXJzdCBjbGVhciBhbGwgYml0cyB0aGF0IGFyZSBiZXlvbmQgdGhlIHR5cGUncyBwcmVjaXNpb24uICAqLwoKICBpZiAocHJlYyA9PSAyICogSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKICAgIDsKICBlbHNlIGlmIChwcmVjID4gSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKICAgIFRSRUVfSU5UX0NTVF9ISUdIICh0KQogICAgICAmPSB+KChIT1NUX1dJREVfSU5UKSAoLTEpIDw8IChwcmVjIC0gSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkpOwogIGVsc2UKICAgIHsKICAgICAgVFJFRV9JTlRfQ1NUX0hJR0ggKHQpID0gMDsKICAgICAgaWYgKHByZWMgPCBIT1NUX0JJVFNfUEVSX1dJREVfSU5UKQoJVFJFRV9JTlRfQ1NUX0xPVyAodCkgJj0gfigodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgKC0xKSA8PCBwcmVjKTsKICAgIH0KCiAgLyogVW5zaWduZWQgdHlwZXMgZG8gbm90IHN1ZmZlciBzaWduIGV4dGVuc2lvbiBvciBvdmVyZmxvdyB1bmxlc3MgdGhleQogICAgIGFyZSBhIHNpemV0eXBlLiAgKi8KICBpZiAoVFJFRV9VTlNJR05FRCAoVFJFRV9UWVBFICh0KSkKICAgICAgJiYgISAoVFJFRV9DT0RFIChUUkVFX1RZUEUgKHQpKSA9PSBJTlRFR0VSX1RZUEUKCSAgICAmJiBUWVBFX0lTX1NJWkVUWVBFIChUUkVFX1RZUEUgKHQpKSkpCiAgICByZXR1cm4gb3ZlcmZsb3c7CgogIC8qIElmIHRoZSB2YWx1ZSdzIHNpZ24gYml0IGlzIHNldCwgZXh0ZW5kIHRoZSBzaWduLiAgKi8KICBpZiAocHJlYyAhPSAyICogSE9TVF9CSVRTX1BFUl9XSURFX0lOVAogICAgICAmJiAocHJlYyA+IEhPU1RfQklUU19QRVJfV0lERV9JTlQKCSAgPyAwICE9IChUUkVFX0lOVF9DU1RfSElHSCAodCkKCQkgICYgKChIT1NUX1dJREVfSU5UKSAxCgkJICAgICA8PCAocHJlYyAtIEhPU1RfQklUU19QRVJfV0lERV9JTlQgLSAxKSkpCgkgIDogMCAhPSAoVFJFRV9JTlRfQ1NUX0xPVyAodCkKCQkgICYgKCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSAxIDw8IChwcmVjIC0gMSkpKSkpCiAgICB7CiAgICAgIC8qIFZhbHVlIGlzIG5lZ2F0aXZlOgoJIHNldCB0byAxIGFsbCB0aGUgYml0cyB0aGF0IGFyZSBvdXRzaWRlIHRoaXMgdHlwZSdzIHByZWNpc2lvbi4gICovCiAgICAgIGlmIChwcmVjID4gSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKCVRSRUVfSU5UX0NTVF9ISUdIICh0KQoJICB8PSAoKEhPU1RfV0lERV9JTlQpICgtMSkgPDwgKHByZWMgLSBIT1NUX0JJVFNfUEVSX1dJREVfSU5UKSk7CiAgICAgIGVsc2UKCXsKCSAgVFJFRV9JTlRfQ1NUX0hJR0ggKHQpID0gLTE7CgkgIGlmIChwcmVjIDwgSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKCSAgICBUUkVFX0lOVF9DU1RfTE9XICh0KSB8PSAoKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQpICgtMSkgPDwgcHJlYyk7Cgl9CiAgICB9CgogIC8qIFJldHVybiBub256ZXJvIGlmIHNpZ25lZCBvdmVyZmxvdyBvY2N1cnJlZC4gICovCiAgcmV0dXJuCiAgICAoKG92ZXJmbG93IHwgKGxvdyBeIFRSRUVfSU5UX0NTVF9MT1cgKHQpKSB8IChoaWdoIF4gVFJFRV9JTlRfQ1NUX0hJR0ggKHQpKSkKICAgICAhPSAwKTsKfQoMCi8qIEFkZCB0d28gZG91Ymxld29yZCBpbnRlZ2VycyB3aXRoIGRvdWJsZXdvcmQgcmVzdWx0LgogICBFYWNoIGFyZ3VtZW50IGlzIGdpdmVuIGFzIHR3byBgSE9TVF9XSURFX0lOVCcgcGllY2VzLgogICBPbmUgYXJndW1lbnQgaXMgTDEgYW5kIEgxOyB0aGUgb3RoZXIsIEwyIGFuZCBIMi4KICAgVGhlIHZhbHVlIGlzIHN0b3JlZCBhcyB0d28gYEhPU1RfV0lERV9JTlQnIHBpZWNlcyBpbiAqTFYgYW5kICpIVi4gICovCgppbnQKYWRkX2RvdWJsZSAodW5zaWduZWQgSE9TVF9XSURFX0lOVCBsMSwgSE9TVF9XSURFX0lOVCBoMSwKCSAgICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGwyLCBIT1NUX1dJREVfSU5UIGgyLAoJICAgIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgKmx2LCBIT1NUX1dJREVfSU5UICpodikKewogIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgbDsKICBIT1NUX1dJREVfSU5UIGg7CgogIGwgPSBsMSArIGwyOwogIGggPSBoMSArIGgyICsgKGwgPCBsMSk7CgogICpsdiA9IGw7CiAgKmh2ID0gaDsKICByZXR1cm4gT1ZFUkZMT1dfU1VNX1NJR04gKGgxLCBoMiwgaCk7Cn0KCi8qIE5lZ2F0ZSBhIGRvdWJsZXdvcmQgaW50ZWdlciB3aXRoIGRvdWJsZXdvcmQgcmVzdWx0LgogICBSZXR1cm4gbm9uemVybyBpZiB0aGUgb3BlcmF0aW9uIG92ZXJmbG93cywgYXNzdW1pbmcgaXQncyBzaWduZWQuCiAgIFRoZSBhcmd1bWVudCBpcyBnaXZlbiBhcyB0d28gYEhPU1RfV0lERV9JTlQnIHBpZWNlcyBpbiBMMSBhbmQgSDEuCiAgIFRoZSB2YWx1ZSBpcyBzdG9yZWQgYXMgdHdvIGBIT1NUX1dJREVfSU5UJyBwaWVjZXMgaW4gKkxWIGFuZCAqSFYuICAqLwoKaW50Cm5lZ19kb3VibGUgKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgbDEsIEhPU1RfV0lERV9JTlQgaDEsCgkgICAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCAqbHYsIEhPU1RfV0lERV9JTlQgKmh2KQp7CiAgaWYgKGwxID09IDApCiAgICB7CiAgICAgICpsdiA9IDA7CiAgICAgICpodiA9IC0gaDE7CiAgICAgIHJldHVybiAoKmh2ICYgaDEpIDwgMDsKICAgIH0KICBlbHNlCiAgICB7CiAgICAgICpsdiA9IC1sMTsKICAgICAgKmh2ID0gfmgxOwogICAgICByZXR1cm4gMDsKICAgIH0KfQoMCi8qIE11bHRpcGx5IHR3byBkb3VibGV3b3JkIGludGVnZXJzIHdpdGggZG91Ymxld29yZCByZXN1bHQuCiAgIFJldHVybiBub256ZXJvIGlmIHRoZSBvcGVyYXRpb24gb3ZlcmZsb3dzLCBhc3N1bWluZyBpdCdzIHNpZ25lZC4KICAgRWFjaCBhcmd1bWVudCBpcyBnaXZlbiBhcyB0d28gYEhPU1RfV0lERV9JTlQnIHBpZWNlcy4KICAgT25lIGFyZ3VtZW50IGlzIEwxIGFuZCBIMTsgdGhlIG90aGVyLCBMMiBhbmQgSDIuCiAgIFRoZSB2YWx1ZSBpcyBzdG9yZWQgYXMgdHdvIGBIT1NUX1dJREVfSU5UJyBwaWVjZXMgaW4gKkxWIGFuZCAqSFYuICAqLwoKaW50Cm11bF9kb3VibGUgKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgbDEsIEhPU1RfV0lERV9JTlQgaDEsCgkgICAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCBsMiwgSE9TVF9XSURFX0lOVCBoMiwKCSAgICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UICpsdiwgSE9TVF9XSURFX0lOVCAqaHYpCnsKICBIT1NUX1dJREVfSU5UIGFyZzFbNF07CiAgSE9TVF9XSURFX0lOVCBhcmcyWzRdOwogIEhPU1RfV0lERV9JTlQgcHJvZFs0ICogMl07CiAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCBjYXJyeTsKICBpbnQgaSwgaiwgazsKICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIHRvcGxvdywgbmVnbG93OwogIEhPU1RfV0lERV9JTlQgdG9waGlnaCwgbmVnaGlnaDsKCiAgZW5jb2RlIChhcmcxLCBsMSwgaDEpOwogIGVuY29kZSAoYXJnMiwgbDIsIGgyKTsKCiAgbWVtc2V0IChwcm9kLCAwLCBzaXplb2YgcHJvZCk7CgogIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspCiAgICB7CiAgICAgIGNhcnJ5ID0gMDsKICAgICAgZm9yIChqID0gMDsgaiA8IDQ7IGorKykKCXsKCSAgayA9IGkgKyBqOwoJICAvKiBUaGlzIHByb2R1Y3QgaXMgPD0gMHhGRkZFMDAwMSwgdGhlIHN1bSA8PSAweEZGRkYwMDAwLiAgKi8KCSAgY2FycnkgKz0gYXJnMVtpXSAqIGFyZzJbal07CgkgIC8qIFNpbmNlIHByb2RbcF0gPCAweEZGRkYsIHRoaXMgc3VtIDw9IDB4RkZGRkZGRkYuICAqLwoJICBjYXJyeSArPSBwcm9kW2tdOwoJICBwcm9kW2tdID0gTE9XUEFSVCAoY2FycnkpOwoJICBjYXJyeSA9IEhJR0hQQVJUIChjYXJyeSk7Cgl9CiAgICAgIHByb2RbaSArIDRdID0gY2Fycnk7CiAgICB9CgogIGRlY29kZSAocHJvZCwgbHYsIGh2KTsJLyogVGhpcyBpZ25vcmVzIHByb2RbNF0gdGhyb3VnaCBwcm9kWzQqMi0xXSAqLwoKICAvKiBDaGVjayBmb3Igb3ZlcmZsb3cgYnkgY2FsY3VsYXRpbmcgdGhlIHRvcCBoYWxmIG9mIHRoZSBhbnN3ZXIgaW4gZnVsbDsKICAgICBpdCBzaG91bGQgYWdyZWUgd2l0aCB0aGUgbG93IGhhbGYncyBzaWduIGJpdC4gICovCiAgZGVjb2RlIChwcm9kICsgNCwgJnRvcGxvdywgJnRvcGhpZ2gpOwogIGlmIChoMSA8IDApCiAgICB7CiAgICAgIG5lZ19kb3VibGUgKGwyLCBoMiwgJm5lZ2xvdywgJm5lZ2hpZ2gpOwogICAgICBhZGRfZG91YmxlIChuZWdsb3csIG5lZ2hpZ2gsIHRvcGxvdywgdG9waGlnaCwgJnRvcGxvdywgJnRvcGhpZ2gpOwogICAgfQogIGlmIChoMiA8IDApCiAgICB7CiAgICAgIG5lZ19kb3VibGUgKGwxLCBoMSwgJm5lZ2xvdywgJm5lZ2hpZ2gpOwogICAgICBhZGRfZG91YmxlIChuZWdsb3csIG5lZ2hpZ2gsIHRvcGxvdywgdG9waGlnaCwgJnRvcGxvdywgJnRvcGhpZ2gpOwogICAgfQogIHJldHVybiAoKmh2IDwgMCA/IH4odG9wbG93ICYgdG9waGlnaCkgOiB0b3Bsb3cgfCB0b3BoaWdoKSAhPSAwOwp9CgwKLyogU2hpZnQgdGhlIGRvdWJsZXdvcmQgaW50ZWdlciBpbiBMMSwgSDEgbGVmdCBieSBDT1VOVCBwbGFjZXMKICAga2VlcGluZyBvbmx5IFBSRUMgYml0cyBvZiByZXN1bHQuCiAgIFNoaWZ0IHJpZ2h0IGlmIENPVU5UIGlzIG5lZ2F0aXZlLgogICBBUklUSCBub256ZXJvIHNwZWNpZmllcyBhcml0aG1ldGljIHNoaWZ0aW5nOyBvdGhlcndpc2UgdXNlIGxvZ2ljYWwgc2hpZnQuCiAgIFN0b3JlIHRoZSB2YWx1ZSBhcyB0d28gYEhPU1RfV0lERV9JTlQnIHBpZWNlcyBpbiAqTFYgYW5kICpIVi4gICovCgp2b2lkCmxzaGlmdF9kb3VibGUgKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgbDEsIEhPU1RfV0lERV9JTlQgaDEsCgkgICAgICAgSE9TVF9XSURFX0lOVCBjb3VudCwgdW5zaWduZWQgaW50IHByZWMsCgkgICAgICAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCAqbHYsIEhPU1RfV0lERV9JTlQgKmh2LCBpbnQgYXJpdGgpCnsKICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIHNpZ25tYXNrOwoKICBpZiAoY291bnQgPCAwKQogICAgewogICAgICByc2hpZnRfZG91YmxlIChsMSwgaDEsIC1jb3VudCwgcHJlYywgbHYsIGh2LCBhcml0aCk7CiAgICAgIHJldHVybjsKICAgIH0KCiNpZmRlZiBTSElGVF9DT1VOVF9UUlVOQ0FURUQKICBpZiAoU0hJRlRfQ09VTlRfVFJVTkNBVEVEKQogICAgY291bnQgJT0gcHJlYzsKI2VuZGlmCgogIGlmIChjb3VudCA+PSAyICogSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKICAgIHsKICAgICAgLyogU2hpZnRpbmcgYnkgdGhlIGhvc3Qgd29yZCBzaXplIGlzIHVuZGVmaW5lZCBhY2NvcmRpbmcgdG8gdGhlCgkgQU5TSSBzdGFuZGFyZCwgc28gd2UgbXVzdCBoYW5kbGUgdGhpcyBhcyBhIHNwZWNpYWwgY2FzZS4gICovCiAgICAgICpodiA9IDA7CiAgICAgICpsdiA9IDA7CiAgICB9CiAgZWxzZSBpZiAoY291bnQgPj0gSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKICAgIHsKICAgICAgKmh2ID0gbDEgPDwgKGNvdW50IC0gSE9TVF9CSVRTX1BFUl9XSURFX0lOVCk7CiAgICAgICpsdiA9IDA7CiAgICB9CiAgZWxzZQogICAgewogICAgICAqaHYgPSAoKCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSBoMSA8PCBjb3VudCkKCSAgICAgfCAobDEgPj4gKEhPU1RfQklUU19QRVJfV0lERV9JTlQgLSBjb3VudCAtIDEpID4+IDEpKTsKICAgICAgKmx2ID0gbDEgPDwgY291bnQ7CiAgICB9CgogIC8qIFNpZ24gZXh0ZW5kIGFsbCBiaXRzIHRoYXQgYXJlIGJleW9uZCB0aGUgcHJlY2lzaW9uLiAgKi8KCiAgc2lnbm1hc2sgPSAtKChwcmVjID4gSE9TVF9CSVRTX1BFUl9XSURFX0lOVAoJCT8gKCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSAqaHYKCQkgICA+PiAocHJlYyAtIEhPU1RfQklUU19QRVJfV0lERV9JTlQgLSAxKSkKCQk6ICgqbHYgPj4gKHByZWMgLSAxKSkpICYgMSk7CgogIGlmIChwcmVjID49IDIgKiBIT1NUX0JJVFNfUEVSX1dJREVfSU5UKQogICAgOwogIGVsc2UgaWYgKHByZWMgPj0gSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKICAgIHsKICAgICAgKmh2ICY9IH4oKEhPU1RfV0lERV9JTlQpICgtMSkgPDwgKHByZWMgLSBIT1NUX0JJVFNfUEVSX1dJREVfSU5UKSk7CiAgICAgICpodiB8PSBzaWdubWFzayA8PCAocHJlYyAtIEhPU1RfQklUU19QRVJfV0lERV9JTlQpOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgKmh2ID0gc2lnbm1hc2s7CiAgICAgICpsdiAmPSB+KCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSAoLTEpIDw8IHByZWMpOwogICAgICAqbHYgfD0gc2lnbm1hc2sgPDwgcHJlYzsKICAgIH0KfQoKLyogU2hpZnQgdGhlIGRvdWJsZXdvcmQgaW50ZWdlciBpbiBMMSwgSDEgcmlnaHQgYnkgQ09VTlQgcGxhY2VzCiAgIGtlZXBpbmcgb25seSBQUkVDIGJpdHMgb2YgcmVzdWx0LiAgQ09VTlQgbXVzdCBiZSBwb3NpdGl2ZS4KICAgQVJJVEggbm9uemVybyBzcGVjaWZpZXMgYXJpdGhtZXRpYyBzaGlmdGluZzsgb3RoZXJ3aXNlIHVzZSBsb2dpY2FsIHNoaWZ0LgogICBTdG9yZSB0aGUgdmFsdWUgYXMgdHdvIGBIT1NUX1dJREVfSU5UJyBwaWVjZXMgaW4gKkxWIGFuZCAqSFYuICAqLwoKdm9pZApyc2hpZnRfZG91YmxlICh1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGwxLCBIT1NUX1dJREVfSU5UIGgxLAoJICAgICAgIEhPU1RfV0lERV9JTlQgY291bnQsIHVuc2lnbmVkIGludCBwcmVjLAoJICAgICAgIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgKmx2LCBIT1NUX1dJREVfSU5UICpodiwKCSAgICAgICBpbnQgYXJpdGgpCnsKICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIHNpZ25tYXNrOwoKICBzaWdubWFzayA9IChhcml0aAoJICAgICAgPyAtKCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSBoMSA+PiAoSE9TVF9CSVRTX1BFUl9XSURFX0lOVCAtIDEpKQoJICAgICAgOiAwKTsKCiNpZmRlZiBTSElGVF9DT1VOVF9UUlVOQ0FURUQKICBpZiAoU0hJRlRfQ09VTlRfVFJVTkNBVEVEKQogICAgY291bnQgJT0gcHJlYzsKI2VuZGlmCgogIGlmIChjb3VudCA+PSAyICogSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKICAgIHsKICAgICAgLyogU2hpZnRpbmcgYnkgdGhlIGhvc3Qgd29yZCBzaXplIGlzIHVuZGVmaW5lZCBhY2NvcmRpbmcgdG8gdGhlCgkgQU5TSSBzdGFuZGFyZCwgc28gd2UgbXVzdCBoYW5kbGUgdGhpcyBhcyBhIHNwZWNpYWwgY2FzZS4gICovCiAgICAgICpodiA9IDA7CiAgICAgICpsdiA9IDA7CiAgICB9CiAgZWxzZSBpZiAoY291bnQgPj0gSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKICAgIHsKICAgICAgKmh2ID0gMDsKICAgICAgKmx2ID0gKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQpIGgxID4+IChjb3VudCAtIEhPU1RfQklUU19QRVJfV0lERV9JTlQpOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgKmh2ID0gKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQpIGgxID4+IGNvdW50OwogICAgICAqbHYgPSAoKGwxID4+IGNvdW50KQoJICAgICB8ICgodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgaDEgPDwgKEhPU1RfQklUU19QRVJfV0lERV9JTlQgLSBjb3VudCAtIDEpIDw8IDEpKTsKICAgIH0KCiAgLyogWmVybyAvIHNpZ24gZXh0ZW5kIGFsbCBiaXRzIHRoYXQgYXJlIGJleW9uZCB0aGUgcHJlY2lzaW9uLiAgKi8KCiAgaWYgKGNvdW50ID49IChIT1NUX1dJREVfSU5UKXByZWMpCiAgICB7CiAgICAgICpodiA9IHNpZ25tYXNrOwogICAgICAqbHYgPSBzaWdubWFzazsKICAgIH0KICBlbHNlIGlmICgocHJlYyAtIGNvdW50KSA+PSAyICogSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKICAgIDsKICBlbHNlIGlmICgocHJlYyAtIGNvdW50KSA+PSBIT1NUX0JJVFNfUEVSX1dJREVfSU5UKQogICAgewogICAgICAqaHYgJj0gfigoSE9TVF9XSURFX0lOVCkgKC0xKSA8PCAocHJlYyAtIGNvdW50IC0gSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkpOwogICAgICAqaHYgfD0gc2lnbm1hc2sgPDwgKHByZWMgLSBjb3VudCAtIEhPU1RfQklUU19QRVJfV0lERV9JTlQpOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgKmh2ID0gc2lnbm1hc2s7CiAgICAgICpsdiAmPSB+KCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSAoLTEpIDw8IChwcmVjIC0gY291bnQpKTsKICAgICAgKmx2IHw9IHNpZ25tYXNrIDw8IChwcmVjIC0gY291bnQpOwogICAgfQp9CgwKLyogUm90YXRlIHRoZSBkb3VibGV3b3JkIGludGVnZXIgaW4gTDEsIEgxIGxlZnQgYnkgQ09VTlQgcGxhY2VzCiAgIGtlZXBpbmcgb25seSBQUkVDIGJpdHMgb2YgcmVzdWx0LgogICBSb3RhdGUgcmlnaHQgaWYgQ09VTlQgaXMgbmVnYXRpdmUuCiAgIFN0b3JlIHRoZSB2YWx1ZSBhcyB0d28gYEhPU1RfV0lERV9JTlQnIHBpZWNlcyBpbiAqTFYgYW5kICpIVi4gICovCgp2b2lkCmxyb3RhdGVfZG91YmxlICh1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGwxLCBIT1NUX1dJREVfSU5UIGgxLAoJCUhPU1RfV0lERV9JTlQgY291bnQsIHVuc2lnbmVkIGludCBwcmVjLAoJCXVuc2lnbmVkIEhPU1RfV0lERV9JTlQgKmx2LCBIT1NUX1dJREVfSU5UICpodikKewogIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgczFsLCBzMmw7CiAgSE9TVF9XSURFX0lOVCBzMWgsIHMyaDsKCiAgY291bnQgJT0gcHJlYzsKICBpZiAoY291bnQgPCAwKQogICAgY291bnQgKz0gcHJlYzsKCiAgbHNoaWZ0X2RvdWJsZSAobDEsIGgxLCBjb3VudCwgcHJlYywgJnMxbCwgJnMxaCwgMCk7CiAgcnNoaWZ0X2RvdWJsZSAobDEsIGgxLCBwcmVjIC0gY291bnQsIHByZWMsICZzMmwsICZzMmgsIDApOwogICpsdiA9IHMxbCB8IHMybDsKICAqaHYgPSBzMWggfCBzMmg7Cn0KCi8qIFJvdGF0ZSB0aGUgZG91Ymxld29yZCBpbnRlZ2VyIGluIEwxLCBIMSBsZWZ0IGJ5IENPVU5UIHBsYWNlcwogICBrZWVwaW5nIG9ubHkgUFJFQyBiaXRzIG9mIHJlc3VsdC4gIENPVU5UIG11c3QgYmUgcG9zaXRpdmUuCiAgIFN0b3JlIHRoZSB2YWx1ZSBhcyB0d28gYEhPU1RfV0lERV9JTlQnIHBpZWNlcyBpbiAqTFYgYW5kICpIVi4gICovCgp2b2lkCnJyb3RhdGVfZG91YmxlICh1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGwxLCBIT1NUX1dJREVfSU5UIGgxLAoJCUhPU1RfV0lERV9JTlQgY291bnQsIHVuc2lnbmVkIGludCBwcmVjLAoJCXVuc2lnbmVkIEhPU1RfV0lERV9JTlQgKmx2LCBIT1NUX1dJREVfSU5UICpodikKewogIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgczFsLCBzMmw7CiAgSE9TVF9XSURFX0lOVCBzMWgsIHMyaDsKCiAgY291bnQgJT0gcHJlYzsKICBpZiAoY291bnQgPCAwKQogICAgY291bnQgKz0gcHJlYzsKCiAgcnNoaWZ0X2RvdWJsZSAobDEsIGgxLCBjb3VudCwgcHJlYywgJnMxbCwgJnMxaCwgMCk7CiAgbHNoaWZ0X2RvdWJsZSAobDEsIGgxLCBwcmVjIC0gY291bnQsIHByZWMsICZzMmwsICZzMmgsIDApOwogICpsdiA9IHMxbCB8IHMybDsKICAqaHYgPSBzMWggfCBzMmg7Cn0KDAovKiBEaXZpZGUgZG91Ymxld29yZCBpbnRlZ2VyIExOVU0sIEhOVU0gYnkgZG91Ymxld29yZCBpbnRlZ2VyIExERU4sIEhERU4KICAgZm9yIGEgcXVvdGllbnQgKHN0b3JlZCBpbiAqTFFVTywgKkhRVU8pIGFuZCByZW1haW5kZXIgKGluICpMUkVNLCAqSFJFTSkuCiAgIENPREUgaXMgYSB0cmVlIGNvZGUgZm9yIGEga2luZCBvZiBkaXZpc2lvbiwgb25lIG9mCiAgIFRSVU5DX0RJVl9FWFBSLCBGTE9PUl9ESVZfRVhQUiwgQ0VJTF9ESVZfRVhQUiwgUk9VTkRfRElWX0VYUFIKICAgb3IgRVhBQ1RfRElWX0VYUFIKICAgSXQgY29udHJvbHMgaG93IHRoZSBxdW90aWVudCBpcyByb3VuZGVkIHRvIGFuIGludGVnZXIuCiAgIFJldHVybiBub256ZXJvIGlmIHRoZSBvcGVyYXRpb24gb3ZlcmZsb3dzLgogICBVTlMgbm9uemVybyBzYXlzIGRvIHVuc2lnbmVkIGRpdmlzaW9uLiAgKi8KCmludApkaXZfYW5kX3JvdW5kX2RvdWJsZSAoZW51bSB0cmVlX2NvZGUgY29kZSwgaW50IHVucywKCQkgICAgICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGxudW1fb3JpZywgLyogbnVtID09IG51bWVyYXRvciA9PSBkaXZpZGVuZCAqLwoJCSAgICAgIEhPU1RfV0lERV9JTlQgaG51bV9vcmlnLAoJCSAgICAgIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgbGRlbl9vcmlnLCAvKiBkZW4gPT0gZGVub21pbmF0b3IgPT0gZGl2aXNvciAqLwoJCSAgICAgIEhPU1RfV0lERV9JTlQgaGRlbl9vcmlnLAoJCSAgICAgIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgKmxxdW8sCgkJICAgICAgSE9TVF9XSURFX0lOVCAqaHF1bywgdW5zaWduZWQgSE9TVF9XSURFX0lOVCAqbHJlbSwKCQkgICAgICBIT1NUX1dJREVfSU5UICpocmVtKQp7CiAgaW50IHF1b19uZWcgPSAwOwogIEhPU1RfV0lERV9JTlQgbnVtWzQgKyAxXTsJLyogZXh0cmEgZWxlbWVudCBmb3Igc2NhbGluZy4gICovCiAgSE9TVF9XSURFX0lOVCBkZW5bNF0sIHF1b1s0XTsKICBpbnQgaSwgajsKICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIHdvcms7CiAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCBjYXJyeSA9IDA7CiAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCBsbnVtID0gbG51bV9vcmlnOwogIEhPU1RfV0lERV9JTlQgaG51bSA9IGhudW1fb3JpZzsKICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGxkZW4gPSBsZGVuX29yaWc7CiAgSE9TVF9XSURFX0lOVCBoZGVuID0gaGRlbl9vcmlnOwogIGludCBvdmVyZmxvdyA9IDA7CgogIGlmIChoZGVuID09IDAgJiYgbGRlbiA9PSAwKQogICAgb3ZlcmZsb3cgPSAxLCBsZGVuID0gMTsKCiAgLyogQ2FsY3VsYXRlIHF1b3RpZW50IHNpZ24gYW5kIGNvbnZlcnQgb3BlcmFuZHMgdG8gdW5zaWduZWQuICAqLwogIGlmICghdW5zKQogICAgewogICAgICBpZiAoaG51bSA8IDApCgl7CgkgIHF1b19uZWcgPSB+IHF1b19uZWc7CgkgIC8qIChtaW5pbXVtIGludGVnZXIpIC8gKC0xKSBpcyB0aGUgb25seSBvdmVyZmxvdyBjYXNlLiAgKi8KCSAgaWYgKG5lZ19kb3VibGUgKGxudW0sIGhudW0sICZsbnVtLCAmaG51bSkKCSAgICAgICYmICgoSE9TVF9XSURFX0lOVCkgbGRlbiAmIGhkZW4pID09IC0xKQoJICAgIG92ZXJmbG93ID0gMTsKCX0KICAgICAgaWYgKGhkZW4gPCAwKQoJewoJICBxdW9fbmVnID0gfiBxdW9fbmVnOwoJICBuZWdfZG91YmxlIChsZGVuLCBoZGVuLCAmbGRlbiwgJmhkZW4pOwoJfQogICAgfQoKICBpZiAoaG51bSA9PSAwICYmIGhkZW4gPT0gMCkKICAgIHsJCQkJLyogc2luZ2xlIHByZWNpc2lvbiAqLwogICAgICAqaHF1byA9ICpocmVtID0gMDsKICAgICAgLyogVGhpcyB1bnNpZ25lZCBkaXZpc2lvbiByb3VuZHMgdG93YXJkIHplcm8uICAqLwogICAgICAqbHF1byA9IGxudW0gLyBsZGVuOwogICAgICBnb3RvIGZpbmlzaF91cDsKICAgIH0KCiAgaWYgKGhudW0gPT0gMCkKICAgIHsJCQkJLyogdHJpdmlhbCBjYXNlOiBkaXZpZGVuZCA8IGRpdmlzb3IgKi8KICAgICAgLyogaGRlbiAhPSAwIGFscmVhZHkgY2hlY2tlZC4gICovCiAgICAgICpocXVvID0gKmxxdW8gPSAwOwogICAgICAqaHJlbSA9IGhudW07CiAgICAgICpscmVtID0gbG51bTsKICAgICAgZ290byBmaW5pc2hfdXA7CiAgICB9CgogIG1lbXNldCAocXVvLCAwLCBzaXplb2YgcXVvKTsKCiAgbWVtc2V0IChudW0sIDAsIHNpemVvZiBudW0pOwkvKiB0byB6ZXJvIDl0aCBlbGVtZW50ICovCiAgbWVtc2V0IChkZW4sIDAsIHNpemVvZiBkZW4pOwoKICBlbmNvZGUgKG51bSwgbG51bSwgaG51bSk7CiAgZW5jb2RlIChkZW4sIGxkZW4sIGhkZW4pOwoKICAvKiBTcGVjaWFsIGNvZGUgZm9yIHdoZW4gdGhlIGRpdmlzb3IgPCBCQVNFLiAgKi8KICBpZiAoaGRlbiA9PSAwICYmIGxkZW4gPCAodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgQkFTRSkKICAgIHsKICAgICAgLyogaG51bSAhPSAwIGFscmVhZHkgY2hlY2tlZC4gICovCiAgICAgIGZvciAoaSA9IDQgLSAxOyBpID49IDA7IGktLSkKCXsKCSAgd29yayA9IG51bVtpXSArIGNhcnJ5ICogQkFTRTsKCSAgcXVvW2ldID0gd29yayAvIGxkZW47CgkgIGNhcnJ5ID0gd29yayAlIGxkZW47Cgl9CiAgICB9CiAgZWxzZQogICAgewogICAgICAvKiBGdWxsIGRvdWJsZSBwcmVjaXNpb24gZGl2aXNpb24sCgkgd2l0aCB0aGFua3MgdG8gRG9uIEtudXRoJ3MgIlNlbWludW1lcmljYWwgQWxnb3JpdGhtcyIuICAqLwogICAgICBpbnQgbnVtX2hpX3NpZywgZGVuX2hpX3NpZzsKICAgICAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCBxdW9fZXN0LCBzY2FsZTsKCiAgICAgIC8qIEZpbmQgdGhlIGhpZ2hlc3Qgbm9uemVybyBkaXZpc29yIGRpZ2l0LiAgKi8KICAgICAgZm9yIChpID0gNCAtIDE7OyBpLS0pCglpZiAoZGVuW2ldICE9IDApCgkgIHsKCSAgICBkZW5faGlfc2lnID0gaTsKCSAgICBicmVhazsKCSAgfQoKICAgICAgLyogSW5zdXJlIHRoYXQgdGhlIGZpcnN0IGRpZ2l0IG9mIHRoZSBkaXZpc29yIGlzIGF0IGxlYXN0IEJBU0UvMi4KCSBUaGlzIGlzIHJlcXVpcmVkIGJ5IHRoZSBxdW90aWVudCBkaWdpdCBlc3RpbWF0aW9uIGFsZ29yaXRobS4gICovCgogICAgICBzY2FsZSA9IEJBU0UgLyAoZGVuW2Rlbl9oaV9zaWddICsgMSk7CiAgICAgIGlmIChzY2FsZSA+IDEpCgl7CQkvKiBzY2FsZSBkaXZpc29yIGFuZCBkaXZpZGVuZCAqLwoJICBjYXJyeSA9IDA7CgkgIGZvciAoaSA9IDA7IGkgPD0gNCAtIDE7IGkrKykKCSAgICB7CgkgICAgICB3b3JrID0gKG51bVtpXSAqIHNjYWxlKSArIGNhcnJ5OwoJICAgICAgbnVtW2ldID0gTE9XUEFSVCAod29yayk7CgkgICAgICBjYXJyeSA9IEhJR0hQQVJUICh3b3JrKTsKCSAgICB9CgoJICBudW1bNF0gPSBjYXJyeTsKCSAgY2FycnkgPSAwOwoJICBmb3IgKGkgPSAwOyBpIDw9IDQgLSAxOyBpKyspCgkgICAgewoJICAgICAgd29yayA9IChkZW5baV0gKiBzY2FsZSkgKyBjYXJyeTsKCSAgICAgIGRlbltpXSA9IExPV1BBUlQgKHdvcmspOwoJICAgICAgY2FycnkgPSBISUdIUEFSVCAod29yayk7CgkgICAgICBpZiAoZGVuW2ldICE9IDApIGRlbl9oaV9zaWcgPSBpOwoJICAgIH0KCX0KCiAgICAgIG51bV9oaV9zaWcgPSA0OwoKICAgICAgLyogTWFpbiBsb29wICovCiAgICAgIGZvciAoaSA9IG51bV9oaV9zaWcgLSBkZW5faGlfc2lnIC0gMTsgaSA+PSAwOyBpLS0pCgl7CgkgIC8qIEd1ZXNzIHRoZSBuZXh0IHF1b3RpZW50IGRpZ2l0LCBxdW9fZXN0LCBieSBkaXZpZGluZyB0aGUgZmlyc3QKCSAgICAgdHdvIHJlbWFpbmluZyBkaXZpZGVuZCBkaWdpdHMgYnkgdGhlIGhpZ2ggb3JkZXIgcXVvdGllbnQgZGlnaXQuCgkgICAgIHF1b19lc3QgaXMgbmV2ZXIgbG93IGFuZCBpcyBhdCBtb3N0IDIgaGlnaC4gICovCgkgIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgdG1wOwoKCSAgbnVtX2hpX3NpZyA9IGkgKyBkZW5faGlfc2lnICsgMTsKCSAgd29yayA9IG51bVtudW1faGlfc2lnXSAqIEJBU0UgKyBudW1bbnVtX2hpX3NpZyAtIDFdOwoJICBpZiAobnVtW251bV9oaV9zaWddICE9IGRlbltkZW5faGlfc2lnXSkKCSAgICBxdW9fZXN0ID0gd29yayAvIGRlbltkZW5faGlfc2lnXTsKCSAgZWxzZQoJICAgIHF1b19lc3QgPSBCQVNFIC0gMTsKCgkgIC8qIFJlZmluZSBxdW9fZXN0IHNvIGl0J3MgdXN1YWxseSBjb3JyZWN0LCBhbmQgYXQgbW9zdCBvbmUgaGlnaC4gICovCgkgIHRtcCA9IHdvcmsgLSBxdW9fZXN0ICogZGVuW2Rlbl9oaV9zaWddOwoJICBpZiAodG1wIDwgQkFTRQoJICAgICAgJiYgKGRlbltkZW5faGlfc2lnIC0gMV0gKiBxdW9fZXN0CgkJICA+ICh0bXAgKiBCQVNFICsgbnVtW251bV9oaV9zaWcgLSAyXSkpKQoJICAgIHF1b19lc3QtLTsKCgkgIC8qIFRyeSBRVU9fRVNUIGFzIHRoZSBxdW90aWVudCBkaWdpdCwgYnkgbXVsdGlwbHlpbmcgdGhlCgkgICAgIGRpdmlzb3IgYnkgUVVPX0VTVCBhbmQgc3VidHJhY3RpbmcgZnJvbSB0aGUgcmVtYWluaW5nIGRpdmlkZW5kLgoJICAgICBLZWVwIGluIG1pbmQgdGhhdCBRVU9fRVNUIGlzIHRoZSBJIC0gMXN0IGRpZ2l0LiAgKi8KCgkgIGNhcnJ5ID0gMDsKCSAgZm9yIChqID0gMDsgaiA8PSBkZW5faGlfc2lnOyBqKyspCgkgICAgewoJICAgICAgd29yayA9IHF1b19lc3QgKiBkZW5bal0gKyBjYXJyeTsKCSAgICAgIGNhcnJ5ID0gSElHSFBBUlQgKHdvcmspOwoJICAgICAgd29yayA9IG51bVtpICsgal0gLSBMT1dQQVJUICh3b3JrKTsKCSAgICAgIG51bVtpICsgal0gPSBMT1dQQVJUICh3b3JrKTsKCSAgICAgIGNhcnJ5ICs9IEhJR0hQQVJUICh3b3JrKSAhPSAwOwoJICAgIH0KCgkgIC8qIElmIHF1b19lc3Qgd2FzIGhpZ2ggYnkgb25lLCB0aGVuIG51bVtpXSB3ZW50IG5lZ2F0aXZlIGFuZAoJICAgICB3ZSBuZWVkIHRvIGNvcnJlY3QgdGhpbmdzLiAgKi8KCSAgaWYgKG51bVtudW1faGlfc2lnXSA8IChIT1NUX1dJREVfSU5UKSBjYXJyeSkKCSAgICB7CgkgICAgICBxdW9fZXN0LS07CgkgICAgICBjYXJyeSA9IDA7CQkvKiBhZGQgZGl2aXNvciBiYWNrIGluICovCgkgICAgICBmb3IgKGogPSAwOyBqIDw9IGRlbl9oaV9zaWc7IGorKykKCQl7CgkJICB3b3JrID0gbnVtW2kgKyBqXSArIGRlbltqXSArIGNhcnJ5OwoJCSAgY2FycnkgPSBISUdIUEFSVCAod29yayk7CgkJICBudW1baSArIGpdID0gTE9XUEFSVCAod29yayk7CgkJfQoKCSAgICAgIG51bSBbbnVtX2hpX3NpZ10gKz0gY2Fycnk7CgkgICAgfQoKCSAgLyogU3RvcmUgdGhlIHF1b3RpZW50IGRpZ2l0LiAgKi8KCSAgcXVvW2ldID0gcXVvX2VzdDsKCX0KICAgIH0KCiAgZGVjb2RlIChxdW8sIGxxdW8sIGhxdW8pOwoKIGZpbmlzaF91cDoKICAvKiBJZiByZXN1bHQgaXMgbmVnYXRpdmUsIG1ha2UgaXQgc28uICAqLwogIGlmIChxdW9fbmVnKQogICAgbmVnX2RvdWJsZSAoKmxxdW8sICpocXVvLCBscXVvLCBocXVvKTsKCiAgLyogY29tcHV0ZSB0cmlhbCByZW1haW5kZXI6ICByZW0gPSBudW0gLSAocXVvICogZGVuKSAgKi8KICBtdWxfZG91YmxlICgqbHF1bywgKmhxdW8sIGxkZW5fb3JpZywgaGRlbl9vcmlnLCBscmVtLCBocmVtKTsKICBuZWdfZG91YmxlICgqbHJlbSwgKmhyZW0sIGxyZW0sIGhyZW0pOwogIGFkZF9kb3VibGUgKGxudW1fb3JpZywgaG51bV9vcmlnLCAqbHJlbSwgKmhyZW0sIGxyZW0sIGhyZW0pOwoKICBzd2l0Y2ggKGNvZGUpCiAgICB7CiAgICBjYXNlIFRSVU5DX0RJVl9FWFBSOgogICAgY2FzZSBUUlVOQ19NT0RfRVhQUjoJLyogcm91bmQgdG93YXJkIHplcm8gKi8KICAgIGNhc2UgRVhBQ1RfRElWX0VYUFI6CS8qIGZvciB0aGlzIG9uZSwgaXQgc2hvdWxkbid0IG1hdHRlciAqLwogICAgICByZXR1cm4gb3ZlcmZsb3c7CgogICAgY2FzZSBGTE9PUl9ESVZfRVhQUjoKICAgIGNhc2UgRkxPT1JfTU9EX0VYUFI6CS8qIHJvdW5kIHRvd2FyZCBuZWdhdGl2ZSBpbmZpbml0eSAqLwogICAgICBpZiAocXVvX25lZyAmJiAoKmxyZW0gIT0gMCB8fCAqaHJlbSAhPSAwKSkgICAvKiByYXRpbyA8IDAgJiYgcmVtICE9IDAgKi8KCXsKCSAgLyogcXVvID0gcXVvIC0gMTsgICovCgkgIGFkZF9kb3VibGUgKCpscXVvLCAqaHF1bywgKEhPU1RfV0lERV9JTlQpIC0xLCAoSE9TVF9XSURFX0lOVCkgIC0xLAoJCSAgICAgIGxxdW8sIGhxdW8pOwoJfQogICAgICBlbHNlCglyZXR1cm4gb3ZlcmZsb3c7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ0VJTF9ESVZfRVhQUjoKICAgIGNhc2UgQ0VJTF9NT0RfRVhQUjoJCS8qIHJvdW5kIHRvd2FyZCBwb3NpdGl2ZSBpbmZpbml0eSAqLwogICAgICBpZiAoIXF1b19uZWcgJiYgKCpscmVtICE9IDAgfHwgKmhyZW0gIT0gMCkpICAvKiByYXRpbyA+IDAgJiYgcmVtICE9IDAgKi8KCXsKCSAgYWRkX2RvdWJsZSAoKmxxdW8sICpocXVvLCAoSE9TVF9XSURFX0lOVCkgMSwgKEhPU1RfV0lERV9JTlQpIDAsCgkJICAgICAgbHF1bywgaHF1byk7Cgl9CiAgICAgIGVsc2UKCXJldHVybiBvdmVyZmxvdzsKICAgICAgYnJlYWs7CgogICAgY2FzZSBST1VORF9ESVZfRVhQUjoKICAgIGNhc2UgUk9VTkRfTU9EX0VYUFI6CS8qIHJvdW5kIHRvIGNsb3Nlc3QgaW50ZWdlciAqLwogICAgICB7Cgl1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGxhYnNfcmVtID0gKmxyZW07CglIT1NUX1dJREVfSU5UIGhhYnNfcmVtID0gKmhyZW07Cgl1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGxhYnNfZGVuID0gbGRlbiwgbHR3aWNlOwoJSE9TVF9XSURFX0lOVCBoYWJzX2RlbiA9IGhkZW4sIGh0d2ljZTsKCgkvKiBHZXQgYWJzb2x1dGUgdmFsdWVzLiAgKi8KCWlmICgqaHJlbSA8IDApCgkgIG5lZ19kb3VibGUgKCpscmVtLCAqaHJlbSwgJmxhYnNfcmVtLCAmaGFic19yZW0pOwoJaWYgKGhkZW4gPCAwKQoJICBuZWdfZG91YmxlIChsZGVuLCBoZGVuLCAmbGFic19kZW4sICZoYWJzX2Rlbik7CgoJLyogSWYgKDIgKiBhYnMgKGxyZW0pID49IGFicyAobGRlbikpICovCgltdWxfZG91YmxlICgoSE9TVF9XSURFX0lOVCkgMiwgKEhPU1RfV0lERV9JTlQpIDAsCgkJICAgIGxhYnNfcmVtLCBoYWJzX3JlbSwgJmx0d2ljZSwgJmh0d2ljZSk7CgoJaWYgKCgodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgaGFic19kZW4KCSAgICAgPCAodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgaHR3aWNlKQoJICAgIHx8ICgoKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQpIGhhYnNfZGVuCgkJID09ICh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSBodHdpY2UpCgkJJiYgKGxhYnNfZGVuIDwgbHR3aWNlKSkpCgkgIHsKCSAgICBpZiAoKmhxdW8gPCAwKQoJICAgICAgLyogcXVvID0gcXVvIC0gMTsgICovCgkgICAgICBhZGRfZG91YmxlICgqbHF1bywgKmhxdW8sCgkJCSAgKEhPU1RfV0lERV9JTlQpIC0xLCAoSE9TVF9XSURFX0lOVCkgLTEsIGxxdW8sIGhxdW8pOwoJICAgIGVsc2UKCSAgICAgIC8qIHF1byA9IHF1byArIDE7ICovCgkgICAgICBhZGRfZG91YmxlICgqbHF1bywgKmhxdW8sIChIT1NUX1dJREVfSU5UKSAxLCAoSE9TVF9XSURFX0lOVCkgMCwKCQkJICBscXVvLCBocXVvKTsKCSAgfQoJZWxzZQoJICByZXR1cm4gb3ZlcmZsb3c7CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgYWJvcnQgKCk7CiAgICB9CgogIC8qIENvbXB1dGUgdHJ1ZSByZW1haW5kZXI6ICByZW0gPSBudW0gLSAocXVvICogZGVuKSAgKi8KICBtdWxfZG91YmxlICgqbHF1bywgKmhxdW8sIGxkZW5fb3JpZywgaGRlbl9vcmlnLCBscmVtLCBocmVtKTsKICBuZWdfZG91YmxlICgqbHJlbSwgKmhyZW0sIGxyZW0sIGhyZW0pOwogIGFkZF9kb3VibGUgKGxudW1fb3JpZywgaG51bV9vcmlnLCAqbHJlbSwgKmhyZW0sIGxyZW0sIGhyZW0pOwogIHJldHVybiBvdmVyZmxvdzsKfQoMCi8qIFJldHVybiB0cnVlIGlmIGJ1aWx0LWluIG1hdGhlbWF0aWNhbCBmdW5jdGlvbiBzcGVjaWZpZWQgYnkgQ09ERQogICBwcmVzZXJ2ZXMgdGhlIHNpZ24gb2YgaXQgYXJndW1lbnQsIGkuZS4gLWYoeCkgPT0gZigteCkuICAqLwoKc3RhdGljIGJvb2wKbmVnYXRlX21hdGhmbl9wIChlbnVtIGJ1aWx0X2luX2Z1bmN0aW9uIGNvZGUpCnsKICBzd2l0Y2ggKGNvZGUpCiAgICB7CiAgICBjYXNlIEJVSUxUX0lOX0FTSU46CiAgICBjYXNlIEJVSUxUX0lOX0FTSU5GOgogICAgY2FzZSBCVUlMVF9JTl9BU0lOTDoKICAgIGNhc2UgQlVJTFRfSU5fQVRBTjoKICAgIGNhc2UgQlVJTFRfSU5fQVRBTkY6CiAgICBjYXNlIEJVSUxUX0lOX0FUQU5MOgogICAgY2FzZSBCVUlMVF9JTl9TSU46CiAgICBjYXNlIEJVSUxUX0lOX1NJTkY6CiAgICBjYXNlIEJVSUxUX0lOX1NJTkw6CiAgICBjYXNlIEJVSUxUX0lOX1RBTjoKICAgIGNhc2UgQlVJTFRfSU5fVEFORjoKICAgIGNhc2UgQlVJTFRfSU5fVEFOTDoKICAgICAgcmV0dXJuIHRydWU7CgogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgICB9CiAgcmV0dXJuIGZhbHNlOwp9CgoKLyogRGV0ZXJtaW5lIHdoZXRoZXIgYW4gZXhwcmVzc2lvbiBUIGNhbiBiZSBjaGVhcGx5IG5lZ2F0ZWQgdXNpbmcKICAgdGhlIGZ1bmN0aW9uIG5lZ2F0ZV9leHByLiAgKi8KCnN0YXRpYyBib29sCm5lZ2F0ZV9leHByX3AgKHRyZWUgdCkKewogIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgdmFsOwogIHVuc2lnbmVkIGludCBwcmVjOwogIHRyZWUgdHlwZTsKCiAgaWYgKHQgPT0gMCkKICAgIHJldHVybiBmYWxzZTsKCiAgdHlwZSA9IFRSRUVfVFlQRSAodCk7CgogIFNUUklQX1NJR05fTk9QUyAodCk7CiAgc3dpdGNoIChUUkVFX0NPREUgKHQpKQogICAgewogICAgY2FzZSBJTlRFR0VSX0NTVDoKICAgICAgaWYgKFRSRUVfVU5TSUdORUQgKHR5cGUpIHx8ICEgZmxhZ190cmFwdikKCXJldHVybiB0cnVlOwoKICAgICAgLyogQ2hlY2sgdGhhdCAtQ1NUIHdpbGwgbm90IG92ZXJmbG93IHR5cGUuICAqLwogICAgICBwcmVjID0gVFlQRV9QUkVDSVNJT04gKHR5cGUpOwogICAgICBpZiAocHJlYyA+IEhPU1RfQklUU19QRVJfV0lERV9JTlQpCgl7CgkgIGlmIChUUkVFX0lOVF9DU1RfTE9XICh0KSAhPSAwKQoJICAgIHJldHVybiB0cnVlOwoJICBwcmVjIC09IEhPU1RfQklUU19QRVJfV0lERV9JTlQ7CgkgIHZhbCA9IFRSRUVfSU5UX0NTVF9ISUdIICh0KTsKCX0KICAgICAgZWxzZQoJdmFsID0gVFJFRV9JTlRfQ1NUX0xPVyAodCk7CiAgICAgIGlmIChwcmVjIDwgSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKCXZhbCAmPSAoKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQpIDEgPDwgcHJlYykgLSAxOwogICAgICByZXR1cm4gdmFsICE9ICgodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgMSA8PCAocHJlYyAtIDEpKTsKCiAgICBjYXNlIFJFQUxfQ1NUOgogICAgY2FzZSBORUdBVEVfRVhQUjoKICAgICAgcmV0dXJuIHRydWU7CgogICAgY2FzZSBDT01QTEVYX0NTVDoKICAgICAgcmV0dXJuIG5lZ2F0ZV9leHByX3AgKFRSRUVfUkVBTFBBUlQgKHQpKQoJICAgICAmJiBuZWdhdGVfZXhwcl9wIChUUkVFX0lNQUdQQVJUICh0KSk7CgogICAgY2FzZSBNSU5VU19FWFBSOgogICAgICAvKiBXZSBjYW4ndCB0dXJuIC0oQS1CKSBpbnRvIEItQSB3aGVuIHdlIGhvbm9yIHNpZ25lZCB6ZXJvcy4gICovCiAgICAgIHJldHVybiAoISBGTE9BVF9UWVBFX1AgKHR5cGUpIHx8IGZsYWdfdW5zYWZlX21hdGhfb3B0aW1pemF0aW9ucykKCSAgICAgJiYgcmVvcmRlcl9vcGVyYW5kc19wIChUUkVFX09QRVJBTkQgKHQsIDApLAoJCQkJICAgIFRSRUVfT1BFUkFORCAodCwgMSkpOwoKICAgIGNhc2UgTVVMVF9FWFBSOgogICAgICBpZiAoVFJFRV9VTlNJR05FRCAoVFJFRV9UWVBFICh0KSkpCiAgICAgICAgYnJlYWs7CgogICAgICAvKiBGYWxsIHRocm91Z2guICAqLwoKICAgIGNhc2UgUkRJVl9FWFBSOgogICAgICBpZiAoISBIT05PUl9TSUdOX0RFUEVOREVOVF9ST1VORElORyAoVFlQRV9NT0RFIChUUkVFX1RZUEUgKHQpKSkpCglyZXR1cm4gbmVnYXRlX2V4cHJfcCAoVFJFRV9PUEVSQU5EICh0LCAxKSkKCSAgICAgICB8fCBuZWdhdGVfZXhwcl9wIChUUkVFX09QRVJBTkQgKHQsIDApKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBOT1BfRVhQUjoKICAgICAgLyogTmVnYXRlIC0oKGRvdWJsZSlmbG9hdCkgYXMgKGRvdWJsZSkoLWZsb2F0KS4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKHR5cGUpID09IFJFQUxfVFlQRSkKCXsKCSAgdHJlZSB0ZW0gPSBzdHJpcF9mbG9hdF9leHRlbnNpb25zICh0KTsKCSAgaWYgKHRlbSAhPSB0KQoJICAgIHJldHVybiBuZWdhdGVfZXhwcl9wICh0ZW0pOwoJfQogICAgICBicmVhazsKCiAgICBjYXNlIENBTExfRVhQUjoKICAgICAgLyogTmVnYXRlIC1mKHgpIGFzIGYoLXgpLiAgKi8KICAgICAgaWYgKG5lZ2F0ZV9tYXRoZm5fcCAoYnVpbHRpbl9tYXRoZm5fY29kZSAodCkpKQoJcmV0dXJuIG5lZ2F0ZV9leHByX3AgKFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAodCwgMSkpKTsKICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgICB9CiAgcmV0dXJuIGZhbHNlOwp9CgovKiBHaXZlbiBULCBhbiBleHByZXNzaW9uLCByZXR1cm4gdGhlIG5lZ2F0aW9uIG9mIFQuICBBbGxvdyBmb3IgVCB0byBiZQogICBudWxsLCBpbiB3aGljaCBjYXNlIHJldHVybiBudWxsLiAgKi8KCnN0YXRpYyB0cmVlCm5lZ2F0ZV9leHByICh0cmVlIHQpCnsKICB0cmVlIHR5cGU7CiAgdHJlZSB0ZW07CgogIGlmICh0ID09IDApCiAgICByZXR1cm4gMDsKCiAgdHlwZSA9IFRSRUVfVFlQRSAodCk7CiAgU1RSSVBfU0lHTl9OT1BTICh0KTsKCiAgc3dpdGNoIChUUkVFX0NPREUgKHQpKQogICAgewogICAgY2FzZSBJTlRFR0VSX0NTVDoKICAgICAgewoJdW5zaWduZWQgSE9TVF9XSURFX0lOVCBsb3c7CglIT1NUX1dJREVfSU5UIGhpZ2g7CglpbnQgb3ZlcmZsb3cgPSBuZWdfZG91YmxlIChUUkVFX0lOVF9DU1RfTE9XICh0KSwKCQkJCSAgIFRSRUVfSU5UX0NTVF9ISUdIICh0KSwKCQkJCSAgICZsb3csICZoaWdoKTsKCXRlbSA9IGJ1aWxkX2ludF8yIChsb3csIGhpZ2gpOwoJVFJFRV9UWVBFICh0ZW0pID0gdHlwZTsKCVRSRUVfT1ZFUkZMT1cgKHRlbSkKCSAgPSAoVFJFRV9PVkVSRkxPVyAodCkKCSAgICAgfCBmb3JjZV9maXRfdHlwZSAodGVtLCBvdmVyZmxvdyAmJiAhVFJFRV9VTlNJR05FRCAodHlwZSkpKTsKCVRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKHRlbSkKCSAgPSBUUkVFX09WRVJGTE9XICh0ZW0pIHwgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAodCk7CiAgICAgIH0KICAgICAgaWYgKCEgVFJFRV9PVkVSRkxPVyAodGVtKQoJICB8fCBUUkVFX1VOU0lHTkVEICh0eXBlKQoJICB8fCAhIGZsYWdfdHJhcHYpCglyZXR1cm4gdGVtOwogICAgICBicmVhazsKCiAgICBjYXNlIFJFQUxfQ1NUOgogICAgICB0ZW0gPSBidWlsZF9yZWFsICh0eXBlLCBSRUFMX1ZBTFVFX05FR0FURSAoVFJFRV9SRUFMX0NTVCAodCkpKTsKICAgICAgLyogVHdvJ3MgY29tcGxlbWVudCBGUCBmb3JtYXRzLCBzdWNoIGFzIGM0eCwgbWF5IG92ZXJmbG93LiAgKi8KICAgICAgaWYgKCEgVFJFRV9PVkVSRkxPVyAodGVtKSB8fCAhIGZsYWdfdHJhcHBpbmdfbWF0aCkKCXJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIHRlbSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ09NUExFWF9DU1Q6CiAgICAgIHsKCXRyZWUgcnBhcnQgPSBuZWdhdGVfZXhwciAoVFJFRV9SRUFMUEFSVCAodCkpOwoJdHJlZSBpcGFydCA9IG5lZ2F0ZV9leHByIChUUkVFX0lNQUdQQVJUICh0KSk7CgoJaWYgKChUUkVFX0NPREUgKHJwYXJ0KSA9PSBSRUFMX0NTVAoJICAgICAmJiBUUkVFX0NPREUgKGlwYXJ0KSA9PSBSRUFMX0NTVCkKCSAgICB8fCAoVFJFRV9DT0RFIChycGFydCkgPT0gSU5URUdFUl9DU1QKCQkmJiBUUkVFX0NPREUgKGlwYXJ0KSA9PSBJTlRFR0VSX0NTVCkpCgkgIHJldHVybiBidWlsZF9jb21wbGV4ICh0eXBlLCBycGFydCwgaXBhcnQpOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgTkVHQVRFX0VYUFI6CiAgICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIFRSRUVfT1BFUkFORCAodCwgMCkpOwoKICAgIGNhc2UgTUlOVVNfRVhQUjoKICAgICAgLyogLSAoQSAtIEIpIC0+IEIgLSBBICAqLwogICAgICBpZiAoKCEgRkxPQVRfVFlQRV9QICh0eXBlKSB8fCBmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMpCgkgICYmIHJlb3JkZXJfb3BlcmFuZHNfcCAoVFJFRV9PUEVSQU5EICh0LCAwKSwgVFJFRV9PUEVSQU5EICh0LCAxKSkpCglyZXR1cm4gZm9sZF9jb252ZXJ0ICh0eXBlLAoJCQkgICAgIGZvbGQgKGJ1aWxkIChNSU5VU19FWFBSLCBUUkVFX1RZUEUgKHQpLAoJCQkJCSAgVFJFRV9PUEVSQU5EICh0LCAxKSwKCQkJCQkgIFRSRUVfT1BFUkFORCAodCwgMCkpKSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgTVVMVF9FWFBSOgogICAgICBpZiAoVFJFRV9VTlNJR05FRCAoVFJFRV9UWVBFICh0KSkpCiAgICAgICAgYnJlYWs7CgogICAgICAvKiBGYWxsIHRocm91Z2guICAqLwoKICAgIGNhc2UgUkRJVl9FWFBSOgogICAgICBpZiAoISBIT05PUl9TSUdOX0RFUEVOREVOVF9ST1VORElORyAoVFlQRV9NT0RFIChUUkVFX1RZUEUgKHQpKSkpCgl7CgkgIHRlbSA9IFRSRUVfT1BFUkFORCAodCwgMSk7CgkgIGlmIChuZWdhdGVfZXhwcl9wICh0ZW0pKQoJICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsCgkJCQkgZm9sZCAoYnVpbGQgKFRSRUVfQ09ERSAodCksIFRSRUVfVFlQRSAodCksCgkJCQkJICAgICAgVFJFRV9PUEVSQU5EICh0LCAwKSwKCQkJCQkgICAgICBuZWdhdGVfZXhwciAodGVtKSkpKTsKCSAgdGVtID0gVFJFRV9PUEVSQU5EICh0LCAwKTsKCSAgaWYgKG5lZ2F0ZV9leHByX3AgKHRlbSkpCgkgICAgcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwKCQkJCSBmb2xkIChidWlsZCAoVFJFRV9DT0RFICh0KSwgVFJFRV9UWVBFICh0KSwKCQkJCQkgICAgICBuZWdhdGVfZXhwciAodGVtKSwKCQkJCQkgICAgICBUUkVFX09QRVJBTkQgKHQsIDEpKSkpOwoJfQogICAgICBicmVhazsKCiAgICBjYXNlIE5PUF9FWFBSOgogICAgICAvKiBDb252ZXJ0IC0oKGRvdWJsZSlmbG9hdCkgaW50byAoZG91YmxlKSgtZmxvYXQpLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gUkVBTF9UWVBFKQoJewoJICB0ZW0gPSBzdHJpcF9mbG9hdF9leHRlbnNpb25zICh0KTsKCSAgaWYgKHRlbSAhPSB0ICYmIG5lZ2F0ZV9leHByX3AgKHRlbSkpCgkgICAgcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgbmVnYXRlX2V4cHIgKHRlbSkpOwoJfQogICAgICBicmVhazsKCiAgICBjYXNlIENBTExfRVhQUjoKICAgICAgLyogTmVnYXRlIC1mKHgpIGFzIGYoLXgpLiAgKi8KICAgICAgaWYgKG5lZ2F0ZV9tYXRoZm5fcCAoYnVpbHRpbl9tYXRoZm5fY29kZSAodCkpCgkgICYmIG5lZ2F0ZV9leHByX3AgKFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAodCwgMSkpKSkKCXsKCSAgdHJlZSBmbmRlY2wsIGFyZywgYXJnbGlzdDsKCgkgIGZuZGVjbCA9IGdldF9jYWxsZWVfZm5kZWNsICh0KTsKCSAgYXJnID0gbmVnYXRlX2V4cHIgKFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAodCwgMSkpKTsKCSAgYXJnbGlzdCA9IGJ1aWxkX3RyZWVfbGlzdCAoTlVMTF9UUkVFLCBhcmcpOwoJICByZXR1cm4gYnVpbGRfZnVuY3Rpb25fY2FsbF9leHByIChmbmRlY2wsIGFyZ2xpc3QpOwoJfQogICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICAgIH0KCiAgdGVtID0gZm9sZCAoYnVpbGQxIChORUdBVEVfRVhQUiwgVFJFRV9UWVBFICh0KSwgdCkpOwogIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIHRlbSk7Cn0KDAovKiBTcGxpdCBhIHRyZWUgSU4gaW50byBhIGNvbnN0YW50LCBsaXRlcmFsIGFuZCB2YXJpYWJsZSBwYXJ0cyB0aGF0IGNvdWxkIGJlCiAgIGNvbWJpbmVkIHdpdGggQ09ERSB0byBtYWtlIElOLiAgImNvbnN0YW50IiBtZWFucyBhbiBleHByZXNzaW9uIHdpdGgKICAgVFJFRV9DT05TVEFOVCBidXQgdGhhdCBpc24ndCBhbiBhY3R1YWwgY29uc3RhbnQuICBDT0RFIG11c3QgYmUgYQogICBjb21tdXRhdGl2ZSBhcml0aG1ldGljIG9wZXJhdGlvbi4gIFN0b3JlIHRoZSBjb25zdGFudCBwYXJ0IGludG8gKkNPTlAsCiAgIHRoZSBsaXRlcmFsIGluICpMSVRQIGFuZCByZXR1cm4gdGhlIHZhcmlhYmxlIHBhcnQuICBJZiBhIHBhcnQgaXNuJ3QKICAgcHJlc2VudCwgc2V0IGl0IHRvIG51bGwuICBJZiB0aGUgdHJlZSBkb2VzIG5vdCBkZWNvbXBvc2UgaW4gdGhpcyB3YXksCiAgIHJldHVybiB0aGUgZW50aXJlIHRyZWUgYXMgdGhlIHZhcmlhYmxlIHBhcnQgYW5kIHRoZSBvdGhlciBwYXJ0cyBhcyBudWxsLgoKICAgSWYgQ09ERSBpcyBQTFVTX0VYUFIgd2UgYWxzbyBzcGxpdCB0cmVlcyB0aGF0IHVzZSBNSU5VU19FWFBSLiAgSW4gdGhhdAogICBjYXNlLCB3ZSBuZWdhdGUgYW4gb3BlcmFuZCB0aGF0IHdhcyBzdWJ0cmFjdGVkLiAgRXhjZXB0IGlmIGl0IGlzIGEKICAgbGl0ZXJhbCBmb3Igd2hpY2ggd2UgdXNlICpNSU5VU19MSVRQIGluc3RlYWQuCgogICBJZiBORUdBVEVfUCBpcyB0cnVlLCB3ZSBhcmUgbmVnYXRpbmcgYWxsIG9mIElOLCBhZ2FpbiBleGNlcHQgYSBsaXRlcmFsCiAgIGZvciB3aGljaCB3ZSB1c2UgKk1JTlVTX0xJVFAgaW5zdGVhZC4KCiAgIElmIElOIGlzIGl0c2VsZiBhIGxpdGVyYWwgb3IgY29uc3RhbnQsIHJldHVybiBpdCBhcyBhcHByb3ByaWF0ZS4KCiAgIE5vdGUgdGhhdCB3ZSBkbyBub3QgZ3VhcmFudGVlIHRoYXQgYW55IG9mIHRoZSB0aHJlZSB2YWx1ZXMgd2lsbCBiZSB0aGUKICAgc2FtZSB0eXBlIGFzIElOLCBidXQgdGhleSB3aWxsIGhhdmUgdGhlIHNhbWUgc2lnbmVkbmVzcyBhbmQgbW9kZS4gICovCgpzdGF0aWMgdHJlZQpzcGxpdF90cmVlICh0cmVlIGluLCBlbnVtIHRyZWVfY29kZSBjb2RlLCB0cmVlICpjb25wLCB0cmVlICpsaXRwLAoJICAgIHRyZWUgKm1pbnVzX2xpdHAsIGludCBuZWdhdGVfcCkKewogIHRyZWUgdmFyID0gMDsKCiAgKmNvbnAgPSAwOwogICpsaXRwID0gMDsKICAqbWludXNfbGl0cCA9IDA7CgogIC8qIFN0cmlwIGFueSBjb252ZXJzaW9ucyB0aGF0IGRvbid0IGNoYW5nZSB0aGUgbWFjaGluZSBtb2RlIG9yIHNpZ25lZG5lc3MuICAqLwogIFNUUklQX1NJR05fTk9QUyAoaW4pOwoKICBpZiAoVFJFRV9DT0RFIChpbikgPT0gSU5URUdFUl9DU1QgfHwgVFJFRV9DT0RFIChpbikgPT0gUkVBTF9DU1QpCiAgICAqbGl0cCA9IGluOwogIGVsc2UgaWYgKFRSRUVfQ09ERSAoaW4pID09IGNvZGUKCSAgIHx8ICghIEZMT0FUX1RZUEVfUCAoVFJFRV9UWVBFIChpbikpCgkgICAgICAgLyogV2UgY2FuIGFzc29jaWF0ZSBhZGRpdGlvbiBhbmQgc3VidHJhY3Rpb24gdG9nZXRoZXIgKGV2ZW4KCQkgIHRob3VnaCB0aGUgQyBzdGFuZGFyZCBkb2Vzbid0IHNheSBzbykgZm9yIGludGVnZXJzIGJlY2F1c2UKCQkgIHRoZSB2YWx1ZSBpcyBub3QgYWZmZWN0ZWQuICBGb3IgcmVhbHMsIHRoZSB2YWx1ZSBtaWdodCBiZQoJCSAgYWZmZWN0ZWQsIHNvIHdlIGNhbid0LiAgKi8KCSAgICAgICAmJiAoKGNvZGUgPT0gUExVU19FWFBSICYmIFRSRUVfQ09ERSAoaW4pID09IE1JTlVTX0VYUFIpCgkJICAgfHwgKGNvZGUgPT0gTUlOVVNfRVhQUiAmJiBUUkVFX0NPREUgKGluKSA9PSBQTFVTX0VYUFIpKSkpCiAgICB7CiAgICAgIHRyZWUgb3AwID0gVFJFRV9PUEVSQU5EIChpbiwgMCk7CiAgICAgIHRyZWUgb3AxID0gVFJFRV9PUEVSQU5EIChpbiwgMSk7CiAgICAgIGludCBuZWcxX3AgPSBUUkVFX0NPREUgKGluKSA9PSBNSU5VU19FWFBSOwogICAgICBpbnQgbmVnX2xpdHBfcCA9IDAsIG5lZ19jb25wX3AgPSAwLCBuZWdfdmFyX3AgPSAwOwoKICAgICAgLyogRmlyc3Qgc2VlIGlmIGVpdGhlciBvZiB0aGUgb3BlcmFuZHMgaXMgYSBsaXRlcmFsLCB0aGVuIGEgY29uc3RhbnQuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChvcDApID09IElOVEVHRVJfQ1NUIHx8IFRSRUVfQ09ERSAob3AwKSA9PSBSRUFMX0NTVCkKCSpsaXRwID0gb3AwLCBvcDAgPSAwOwogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKG9wMSkgPT0gSU5URUdFUl9DU1QgfHwgVFJFRV9DT0RFIChvcDEpID09IFJFQUxfQ1NUKQoJKmxpdHAgPSBvcDEsIG5lZ19saXRwX3AgPSBuZWcxX3AsIG9wMSA9IDA7CgogICAgICBpZiAob3AwICE9IDAgJiYgVFJFRV9DT05TVEFOVCAob3AwKSkKCSpjb25wID0gb3AwLCBvcDAgPSAwOwogICAgICBlbHNlIGlmIChvcDEgIT0gMCAmJiBUUkVFX0NPTlNUQU5UIChvcDEpKQoJKmNvbnAgPSBvcDEsIG5lZ19jb25wX3AgPSBuZWcxX3AsIG9wMSA9IDA7CgogICAgICAvKiBJZiB3ZSBoYXZlbid0IGRlYWx0IHdpdGggZWl0aGVyIG9wZXJhbmQsIHRoaXMgaXMgbm90IGEgY2FzZSB3ZSBjYW4KCSBkZWNvbXBvc2UuICBPdGhlcndpc2UsIFZBUiBpcyBlaXRoZXIgb2YgdGhlIG9uZXMgcmVtYWluaW5nLCBpZiBhbnkuICAqLwogICAgICBpZiAob3AwICE9IDAgJiYgb3AxICE9IDApCgl2YXIgPSBpbjsKICAgICAgZWxzZSBpZiAob3AwICE9IDApCgl2YXIgPSBvcDA7CiAgICAgIGVsc2UKCXZhciA9IG9wMSwgbmVnX3Zhcl9wID0gbmVnMV9wOwoKICAgICAgLyogTm93IGRvIGFueSBuZWVkZWQgbmVnYXRpb25zLiAgKi8KICAgICAgaWYgKG5lZ19saXRwX3ApCgkqbWludXNfbGl0cCA9ICpsaXRwLCAqbGl0cCA9IDA7CiAgICAgIGlmIChuZWdfY29ucF9wKQoJKmNvbnAgPSBuZWdhdGVfZXhwciAoKmNvbnApOwogICAgICBpZiAobmVnX3Zhcl9wKQoJdmFyID0gbmVnYXRlX2V4cHIgKHZhcik7CiAgICB9CiAgZWxzZSBpZiAoVFJFRV9DT05TVEFOVCAoaW4pKQogICAgKmNvbnAgPSBpbjsKICBlbHNlCiAgICB2YXIgPSBpbjsKCiAgaWYgKG5lZ2F0ZV9wKQogICAgewogICAgICBpZiAoKmxpdHApCgkqbWludXNfbGl0cCA9ICpsaXRwLCAqbGl0cCA9IDA7CiAgICAgIGVsc2UgaWYgKCptaW51c19saXRwKQoJKmxpdHAgPSAqbWludXNfbGl0cCwgKm1pbnVzX2xpdHAgPSAwOwogICAgICAqY29ucCA9IG5lZ2F0ZV9leHByICgqY29ucCk7CiAgICAgIHZhciA9IG5lZ2F0ZV9leHByICh2YXIpOwogICAgfQoKICByZXR1cm4gdmFyOwp9CgovKiBSZS1hc3NvY2lhdGUgdHJlZXMgc3BsaXQgYnkgdGhlIGFib3ZlIGZ1bmN0aW9uLiAgVDEgYW5kIFQyIGFyZSBlaXRoZXIKICAgZXhwcmVzc2lvbnMgdG8gYXNzb2NpYXRlIG9yIG51bGwuICBSZXR1cm4gdGhlIG5ldyBleHByZXNzaW9uLCBpZiBhbnkuICBJZgogICB3ZSBidWlsZCBhbiBvcGVyYXRpb24sIGRvIGl0IGluIFRZUEUgYW5kIHdpdGggQ09ERS4gICovCgpzdGF0aWMgdHJlZQphc3NvY2lhdGVfdHJlZXMgKHRyZWUgdDEsIHRyZWUgdDIsIGVudW0gdHJlZV9jb2RlIGNvZGUsIHRyZWUgdHlwZSkKewogIGlmICh0MSA9PSAwKQogICAgcmV0dXJuIHQyOwogIGVsc2UgaWYgKHQyID09IDApCiAgICByZXR1cm4gdDE7CgogIC8qIElmIGVpdGhlciBpbnB1dCBpcyBDT0RFLCBhIFBMVVNfRVhQUiwgb3IgYSBNSU5VU19FWFBSLCBkb24ndAogICAgIHRyeSB0byBmb2xkIHRoaXMgc2luY2Ugd2Ugd2lsbCBoYXZlIGluZmluaXRlIHJlY3Vyc2lvbi4gIEJ1dCBkbwogICAgIGRlYWwgd2l0aCBhbnkgTkVHQVRFX0VYUFJzLiAgKi8KICBpZiAoVFJFRV9DT0RFICh0MSkgPT0gY29kZSB8fCBUUkVFX0NPREUgKHQyKSA9PSBjb2RlCiAgICAgIHx8IFRSRUVfQ09ERSAodDEpID09IE1JTlVTX0VYUFIgfHwgVFJFRV9DT0RFICh0MikgPT0gTUlOVVNfRVhQUikKICAgIHsKICAgICAgaWYgKGNvZGUgPT0gUExVU19FWFBSKQoJewoJICBpZiAoVFJFRV9DT0RFICh0MSkgPT0gTkVHQVRFX0VYUFIpCgkgICAgcmV0dXJuIGJ1aWxkIChNSU5VU19FWFBSLCB0eXBlLCBmb2xkX2NvbnZlcnQgKHR5cGUsIHQyKSwKCQkJICBmb2xkX2NvbnZlcnQgKHR5cGUsIFRSRUVfT1BFUkFORCAodDEsIDApKSk7CgkgIGVsc2UgaWYgKFRSRUVfQ09ERSAodDIpID09IE5FR0FURV9FWFBSKQoJICAgIHJldHVybiBidWlsZCAoTUlOVVNfRVhQUiwgdHlwZSwgZm9sZF9jb252ZXJ0ICh0eXBlLCB0MSksCgkJCSAgZm9sZF9jb252ZXJ0ICh0eXBlLCBUUkVFX09QRVJBTkQgKHQyLCAwKSkpOwoJfQogICAgICByZXR1cm4gYnVpbGQgKGNvZGUsIHR5cGUsIGZvbGRfY29udmVydCAodHlwZSwgdDEpLAoJCSAgICBmb2xkX2NvbnZlcnQgKHR5cGUsIHQyKSk7CiAgICB9CgogIHJldHVybiBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwgZm9sZF9jb252ZXJ0ICh0eXBlLCB0MSksCgkJICAgICAgZm9sZF9jb252ZXJ0ICh0eXBlLCB0MikpKTsKfQoMCi8qIENvbWJpbmUgdHdvIGludGVnZXIgY29uc3RhbnRzIEFSRzEgYW5kIEFSRzIgdW5kZXIgb3BlcmF0aW9uIENPREUKICAgdG8gcHJvZHVjZSBhIG5ldyBjb25zdGFudC4KCiAgIElmIE5PVFJVTkMgaXMgbm9uemVybywgZG8gbm90IHRydW5jYXRlIHRoZSByZXN1bHQgdG8gZml0IHRoZSBkYXRhIHR5cGUuICAqLwoKc3RhdGljIHRyZWUKaW50X2NvbnN0X2Jpbm9wIChlbnVtIHRyZWVfY29kZSBjb2RlLCB0cmVlIGFyZzEsIHRyZWUgYXJnMiwgaW50IG5vdHJ1bmMpCnsKICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGludDFsLCBpbnQybDsKICBIT1NUX1dJREVfSU5UIGludDFoLCBpbnQyaDsKICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGxvdzsKICBIT1NUX1dJREVfSU5UIGhpOwogIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgZ2FyYmFnZWw7CiAgSE9TVF9XSURFX0lOVCBnYXJiYWdlaDsKICB0cmVlIHQ7CiAgdHJlZSB0eXBlID0gVFJFRV9UWVBFIChhcmcxKTsKICBpbnQgdW5zID0gVFJFRV9VTlNJR05FRCAodHlwZSk7CiAgaW50IGlzX3NpemV0eXBlCiAgICA9IChUUkVFX0NPREUgKHR5cGUpID09IElOVEVHRVJfVFlQRSAmJiBUWVBFX0lTX1NJWkVUWVBFICh0eXBlKSk7CiAgaW50IG92ZXJmbG93ID0gMDsKICBpbnQgbm9fb3ZlcmZsb3cgPSAwOwoKICBpbnQxbCA9IFRSRUVfSU5UX0NTVF9MT1cgKGFyZzEpOwogIGludDFoID0gVFJFRV9JTlRfQ1NUX0hJR0ggKGFyZzEpOwogIGludDJsID0gVFJFRV9JTlRfQ1NUX0xPVyAoYXJnMik7CiAgaW50MmggPSBUUkVFX0lOVF9DU1RfSElHSCAoYXJnMik7CgogIHN3aXRjaCAoY29kZSkKICAgIHsKICAgIGNhc2UgQklUX0lPUl9FWFBSOgogICAgICBsb3cgPSBpbnQxbCB8IGludDJsLCBoaSA9IGludDFoIHwgaW50Mmg7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgQklUX1hPUl9FWFBSOgogICAgICBsb3cgPSBpbnQxbCBeIGludDJsLCBoaSA9IGludDFoIF4gaW50Mmg7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgQklUX0FORF9FWFBSOgogICAgICBsb3cgPSBpbnQxbCAmIGludDJsLCBoaSA9IGludDFoICYgaW50Mmg7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgUlNISUZUX0VYUFI6CiAgICAgIGludDJsID0gLWludDJsOwogICAgY2FzZSBMU0hJRlRfRVhQUjoKICAgICAgLyogSXQncyB1bmNsZWFyIGZyb20gdGhlIEMgc3RhbmRhcmQgd2hldGhlciBzaGlmdHMgY2FuIG92ZXJmbG93LgoJIFRoZSBmb2xsb3dpbmcgY29kZSBpZ25vcmVzIG92ZXJmbG93OyBwZXJoYXBzIGEgQyBzdGFuZGFyZAoJIGludGVycHJldGF0aW9uIHJ1bGluZyBpcyBuZWVkZWQuICAqLwogICAgICBsc2hpZnRfZG91YmxlIChpbnQxbCwgaW50MWgsIGludDJsLCBUWVBFX1BSRUNJU0lPTiAodHlwZSksCgkJICAgICAmbG93LCAmaGksICF1bnMpOwogICAgICBub19vdmVyZmxvdyA9IDE7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgUlJPVEFURV9FWFBSOgogICAgICBpbnQybCA9IC0gaW50Mmw7CiAgICBjYXNlIExST1RBVEVfRVhQUjoKICAgICAgbHJvdGF0ZV9kb3VibGUgKGludDFsLCBpbnQxaCwgaW50MmwsIFRZUEVfUFJFQ0lTSU9OICh0eXBlKSwKCQkgICAgICAmbG93LCAmaGkpOwogICAgICBicmVhazsKCiAgICBjYXNlIFBMVVNfRVhQUjoKICAgICAgb3ZlcmZsb3cgPSBhZGRfZG91YmxlIChpbnQxbCwgaW50MWgsIGludDJsLCBpbnQyaCwgJmxvdywgJmhpKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBNSU5VU19FWFBSOgogICAgICBuZWdfZG91YmxlIChpbnQybCwgaW50MmgsICZsb3csICZoaSk7CiAgICAgIGFkZF9kb3VibGUgKGludDFsLCBpbnQxaCwgbG93LCBoaSwgJmxvdywgJmhpKTsKICAgICAgb3ZlcmZsb3cgPSBPVkVSRkxPV19TVU1fU0lHTiAoaGksIGludDJoLCBpbnQxaCk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgTVVMVF9FWFBSOgogICAgICBvdmVyZmxvdyA9IG11bF9kb3VibGUgKGludDFsLCBpbnQxaCwgaW50MmwsIGludDJoLCAmbG93LCAmaGkpOwogICAgICBicmVhazsKCiAgICBjYXNlIFRSVU5DX0RJVl9FWFBSOgogICAgY2FzZSBGTE9PUl9ESVZfRVhQUjogY2FzZSBDRUlMX0RJVl9FWFBSOgogICAgY2FzZSBFWEFDVF9ESVZfRVhQUjoKICAgICAgLyogVGhpcyBpcyBhIHNob3J0Y3V0IGZvciBhIGNvbW1vbiBzcGVjaWFsIGNhc2UuICAqLwogICAgICBpZiAoaW50MmggPT0gMCAmJiAoSE9TVF9XSURFX0lOVCkgaW50MmwgPiAwCgkgICYmICEgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAoYXJnMSkKCSAgJiYgISBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcyKQoJICAmJiBpbnQxaCA9PSAwICYmIChIT1NUX1dJREVfSU5UKSBpbnQxbCA+PSAwKQoJewoJICBpZiAoY29kZSA9PSBDRUlMX0RJVl9FWFBSKQoJICAgIGludDFsICs9IGludDJsIC0gMTsKCgkgIGxvdyA9IGludDFsIC8gaW50MmwsIGhpID0gMDsKCSAgYnJlYWs7Cgl9CgogICAgICAvKiAuLi4gZmFsbCB0aHJvdWdoIC4uLiAgKi8KCiAgICBjYXNlIFJPVU5EX0RJVl9FWFBSOgogICAgICBpZiAoaW50MmggPT0gMCAmJiBpbnQybCA9PSAxKQoJewoJICBsb3cgPSBpbnQxbCwgaGkgPSBpbnQxaDsKCSAgYnJlYWs7Cgl9CiAgICAgIGlmIChpbnQxbCA9PSBpbnQybCAmJiBpbnQxaCA9PSBpbnQyaAoJICAmJiAhIChpbnQxbCA9PSAwICYmIGludDFoID09IDApKQoJewoJICBsb3cgPSAxLCBoaSA9IDA7CgkgIGJyZWFrOwoJfQogICAgICBvdmVyZmxvdyA9IGRpdl9hbmRfcm91bmRfZG91YmxlIChjb2RlLCB1bnMsIGludDFsLCBpbnQxaCwgaW50MmwsIGludDJoLAoJCQkJICAgICAgICZsb3csICZoaSwgJmdhcmJhZ2VsLCAmZ2FyYmFnZWgpOwogICAgICBicmVhazsKCiAgICBjYXNlIFRSVU5DX01PRF9FWFBSOgogICAgY2FzZSBGTE9PUl9NT0RfRVhQUjogY2FzZSBDRUlMX01PRF9FWFBSOgogICAgICAvKiBUaGlzIGlzIGEgc2hvcnRjdXQgZm9yIGEgY29tbW9uIHNwZWNpYWwgY2FzZS4gICovCiAgICAgIGlmIChpbnQyaCA9PSAwICYmIChIT1NUX1dJREVfSU5UKSBpbnQybCA+IDAKCSAgJiYgISBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcxKQoJICAmJiAhIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKGFyZzIpCgkgICYmIGludDFoID09IDAgJiYgKEhPU1RfV0lERV9JTlQpIGludDFsID49IDApCgl7CgkgIGlmIChjb2RlID09IENFSUxfTU9EX0VYUFIpCgkgICAgaW50MWwgKz0gaW50MmwgLSAxOwoJICBsb3cgPSBpbnQxbCAlIGludDJsLCBoaSA9IDA7CgkgIGJyZWFrOwoJfQoKICAgICAgLyogLi4uIGZhbGwgdGhyb3VnaCAuLi4gICovCgogICAgY2FzZSBST1VORF9NT0RfRVhQUjoKICAgICAgb3ZlcmZsb3cgPSBkaXZfYW5kX3JvdW5kX2RvdWJsZSAoY29kZSwgdW5zLAoJCQkJICAgICAgIGludDFsLCBpbnQxaCwgaW50MmwsIGludDJoLAoJCQkJICAgICAgICZnYXJiYWdlbCwgJmdhcmJhZ2VoLCAmbG93LCAmaGkpOwogICAgICBicmVhazsKCiAgICBjYXNlIE1JTl9FWFBSOgogICAgY2FzZSBNQVhfRVhQUjoKICAgICAgaWYgKHVucykKCWxvdyA9ICgoKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQpIGludDFoCgkJPCAodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgaW50MmgpCgkgICAgICAgfHwgKCgodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgaW50MWgKCQkgICAgPT0gKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQpIGludDJoKQoJCSAgICYmIGludDFsIDwgaW50MmwpKTsKICAgICAgZWxzZQoJbG93ID0gKGludDFoIDwgaW50MmgKCSAgICAgICB8fCAoaW50MWggPT0gaW50MmggJiYgaW50MWwgPCBpbnQybCkpOwoKICAgICAgaWYgKGxvdyA9PSAoY29kZSA9PSBNSU5fRVhQUikpCglsb3cgPSBpbnQxbCwgaGkgPSBpbnQxaDsKICAgICAgZWxzZQoJbG93ID0gaW50MmwsIGhpID0gaW50Mmg7CiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIGFib3J0ICgpOwogICAgfQoKICAvKiBJZiB0aGlzIGlzIGZvciBhIHNpemV0eXBlLCBjYW4gYmUgcmVwcmVzZW50ZWQgYXMgb25lIChzaWduZWQpCiAgICAgSE9TVF9XSURFX0lOVCB3b3JkLCBhbmQgZG9lc24ndCBvdmVyZmxvdywgdXNlIHNpemVfaW50IHNpbmNlIGl0IGNhY2hlcwogICAgIGNvbnN0YW50cy4gICovCiAgaWYgKGlzX3NpemV0eXBlCiAgICAgICYmICgoaGkgPT0gMCAmJiAoSE9TVF9XSURFX0lOVCkgbG93ID49IDApCgkgIHx8IChoaSA9PSAtMSAmJiAoSE9TVF9XSURFX0lOVCkgbG93IDwgMCkpCiAgICAgICYmIG92ZXJmbG93ID09IDAgJiYgISBUUkVFX09WRVJGTE9XIChhcmcxKSAmJiAhIFRSRUVfT1ZFUkZMT1cgKGFyZzIpKQogICAgcmV0dXJuIHNpemVfaW50X3R5cGVfd2lkZSAobG93LCB0eXBlKTsKICBlbHNlCiAgICB7CiAgICAgIHQgPSBidWlsZF9pbnRfMiAobG93LCBoaSk7CiAgICAgIFRSRUVfVFlQRSAodCkgPSBUUkVFX1RZUEUgKGFyZzEpOwogICAgfQoKICBUUkVFX09WRVJGTE9XICh0KQogICAgPSAoKG5vdHJ1bmMKCT8gKCF1bnMgfHwgaXNfc2l6ZXR5cGUpICYmIG92ZXJmbG93Cgk6IChmb3JjZV9maXRfdHlwZSAodCwgKCF1bnMgfHwgaXNfc2l6ZXR5cGUpICYmIG92ZXJmbG93KQoJICAgJiYgISBub19vdmVyZmxvdykpCiAgICAgICB8IFRSRUVfT1ZFUkZMT1cgKGFyZzEpCiAgICAgICB8IFRSRUVfT1ZFUkZMT1cgKGFyZzIpKTsKCiAgLyogSWYgd2UncmUgZG9pbmcgYSBzaXplIGNhbGN1bGF0aW9uLCB1bnNpZ25lZCBhcml0aG1ldGljIGRvZXMgb3ZlcmZsb3cuCiAgICAgU28gY2hlY2sgaWYgZm9yY2VfZml0X3R5cGUgdHJ1bmNhdGVkIHRoZSB2YWx1ZS4gICovCiAgaWYgKGlzX3NpemV0eXBlCiAgICAgICYmICEgVFJFRV9PVkVSRkxPVyAodCkKICAgICAgJiYgKFRSRUVfSU5UX0NTVF9ISUdIICh0KSAhPSBoaQoJICB8fCBUUkVFX0lOVF9DU1RfTE9XICh0KSAhPSBsb3cpKQogICAgVFJFRV9PVkVSRkxPVyAodCkgPSAxOwoKICBUUkVFX0NPTlNUQU5UX09WRVJGTE9XICh0KSA9IChUUkVFX09WRVJGTE9XICh0KQoJCQkJfCBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcxKQoJCQkJfCBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcyKSk7CiAgcmV0dXJuIHQ7Cn0KCi8qIENvbWJpbmUgdHdvIGNvbnN0YW50cyBBUkcxIGFuZCBBUkcyIHVuZGVyIG9wZXJhdGlvbiBDT0RFIHRvIHByb2R1Y2UgYSBuZXcKICAgY29uc3RhbnQuICBXZSBhc3N1bWUgQVJHMSBhbmQgQVJHMiBoYXZlIHRoZSBzYW1lIGRhdGEgdHlwZSwgb3IgYXQgbGVhc3QKICAgYXJlIHRoZSBzYW1lIGtpbmQgb2YgY29uc3RhbnQgYW5kIHRoZSBzYW1lIG1hY2hpbmUgbW9kZS4KCiAgIElmIE5PVFJVTkMgaXMgbm9uemVybywgZG8gbm90IHRydW5jYXRlIHRoZSByZXN1bHQgdG8gZml0IHRoZSBkYXRhIHR5cGUuICAqLwoKc3RhdGljIHRyZWUKY29uc3RfYmlub3AgKGVudW0gdHJlZV9jb2RlIGNvZGUsIHRyZWUgYXJnMSwgdHJlZSBhcmcyLCBpbnQgbm90cnVuYykKewogIFNUUklQX05PUFMgKGFyZzEpOwogIFNUUklQX05PUFMgKGFyZzIpOwoKICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBJTlRFR0VSX0NTVCkKICAgIHJldHVybiBpbnRfY29uc3RfYmlub3AgKGNvZGUsIGFyZzEsIGFyZzIsIG5vdHJ1bmMpOwoKICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBSRUFMX0NTVCkKICAgIHsKICAgICAgZW51bSBtYWNoaW5lX21vZGUgbW9kZTsKICAgICAgUkVBTF9WQUxVRV9UWVBFIGQxOwogICAgICBSRUFMX1ZBTFVFX1RZUEUgZDI7CiAgICAgIFJFQUxfVkFMVUVfVFlQRSB2YWx1ZTsKICAgICAgdHJlZSB0LCB0eXBlOwoKICAgICAgZDEgPSBUUkVFX1JFQUxfQ1NUIChhcmcxKTsKICAgICAgZDIgPSBUUkVFX1JFQUxfQ1NUIChhcmcyKTsKCiAgICAgIHR5cGUgPSBUUkVFX1RZUEUgKGFyZzEpOwogICAgICBtb2RlID0gVFlQRV9NT0RFICh0eXBlKTsKCiAgICAgIC8qIERvbid0IHBlcmZvcm0gb3BlcmF0aW9uIGlmIHdlIGhvbm9yIHNpZ25hbGluZyBOYU5zIGFuZAoJIGVpdGhlciBvcGVyYW5kIGlzIGEgTmFOLiAgKi8KICAgICAgaWYgKEhPTk9SX1NOQU5TIChtb2RlKQoJICAmJiAoUkVBTF9WQUxVRV9JU05BTiAoZDEpIHx8IFJFQUxfVkFMVUVfSVNOQU4gKGQyKSkpCglyZXR1cm4gTlVMTF9UUkVFOwoKICAgICAgLyogRG9uJ3QgcGVyZm9ybSBvcGVyYXRpb24gaWYgaXQgd291bGQgcmFpc2UgYSBkaXZpc2lvbgoJIGJ5IHplcm8gZXhjZXB0aW9uLiAgKi8KICAgICAgaWYgKGNvZGUgPT0gUkRJVl9FWFBSCgkgICYmIFJFQUxfVkFMVUVTX0VRVUFMIChkMiwgZGNvbnN0MCkKCSAgJiYgKGZsYWdfdHJhcHBpbmdfbWF0aCB8fCAhIE1PREVfSEFTX0lORklOSVRJRVMgKG1vZGUpKSkKCXJldHVybiBOVUxMX1RSRUU7CgogICAgICAvKiBJZiBlaXRoZXIgb3BlcmFuZCBpcyBhIE5hTiwganVzdCByZXR1cm4gaXQuICBPdGhlcndpc2UsIHNldCB1cAoJIGZvciBmbG9hdGluZy1wb2ludCB0cmFwOyB3ZSByZXR1cm4gYW4gb3ZlcmZsb3cuICAqLwogICAgICBpZiAoUkVBTF9WQUxVRV9JU05BTiAoZDEpKQoJcmV0dXJuIGFyZzE7CiAgICAgIGVsc2UgaWYgKFJFQUxfVkFMVUVfSVNOQU4gKGQyKSkKCXJldHVybiBhcmcyOwoKICAgICAgUkVBTF9BUklUSE1FVElDICh2YWx1ZSwgY29kZSwgZDEsIGQyKTsKCiAgICAgIHQgPSBidWlsZF9yZWFsICh0eXBlLCByZWFsX3ZhbHVlX3RydW5jYXRlIChtb2RlLCB2YWx1ZSkpOwoKICAgICAgVFJFRV9PVkVSRkxPVyAodCkKCT0gKGZvcmNlX2ZpdF90eXBlICh0LCAwKQoJICAgfCBUUkVFX09WRVJGTE9XIChhcmcxKSB8IFRSRUVfT1ZFUkZMT1cgKGFyZzIpKTsKICAgICAgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAodCkKCT0gVFJFRV9PVkVSRkxPVyAodCkKCSAgfCBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcxKQoJICB8IFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKGFyZzIpOwogICAgICByZXR1cm4gdDsKICAgIH0KICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBDT01QTEVYX0NTVCkKICAgIHsKICAgICAgdHJlZSB0eXBlID0gVFJFRV9UWVBFIChhcmcxKTsKICAgICAgdHJlZSByMSA9IFRSRUVfUkVBTFBBUlQgKGFyZzEpOwogICAgICB0cmVlIGkxID0gVFJFRV9JTUFHUEFSVCAoYXJnMSk7CiAgICAgIHRyZWUgcjIgPSBUUkVFX1JFQUxQQVJUIChhcmcyKTsKICAgICAgdHJlZSBpMiA9IFRSRUVfSU1BR1BBUlQgKGFyZzIpOwogICAgICB0cmVlIHQ7CgogICAgICBzd2l0Y2ggKGNvZGUpCgl7CgljYXNlIFBMVVNfRVhQUjoKCSAgdCA9IGJ1aWxkX2NvbXBsZXggKHR5cGUsCgkJCSAgICAgY29uc3RfYmlub3AgKFBMVVNfRVhQUiwgcjEsIHIyLCBub3RydW5jKSwKCQkJICAgICBjb25zdF9iaW5vcCAoUExVU19FWFBSLCBpMSwgaTIsIG5vdHJ1bmMpKTsKCSAgYnJlYWs7CgoJY2FzZSBNSU5VU19FWFBSOgoJICB0ID0gYnVpbGRfY29tcGxleCAodHlwZSwKCQkJICAgICBjb25zdF9iaW5vcCAoTUlOVVNfRVhQUiwgcjEsIHIyLCBub3RydW5jKSwKCQkJICAgICBjb25zdF9iaW5vcCAoTUlOVVNfRVhQUiwgaTEsIGkyLCBub3RydW5jKSk7CgkgIGJyZWFrOwoKCWNhc2UgTVVMVF9FWFBSOgoJICB0ID0gYnVpbGRfY29tcGxleCAodHlwZSwKCQkJICAgICBjb25zdF9iaW5vcCAoTUlOVVNfRVhQUiwKCQkJCQkgIGNvbnN0X2Jpbm9wIChNVUxUX0VYUFIsCgkJCQkJCSAgICAgICByMSwgcjIsIG5vdHJ1bmMpLAoJCQkJCSAgY29uc3RfYmlub3AgKE1VTFRfRVhQUiwKCQkJCQkJICAgICAgIGkxLCBpMiwgbm90cnVuYyksCgkJCQkJICBub3RydW5jKSwKCQkJICAgICBjb25zdF9iaW5vcCAoUExVU19FWFBSLAoJCQkJCSAgY29uc3RfYmlub3AgKE1VTFRfRVhQUiwKCQkJCQkJICAgICAgIHIxLCBpMiwgbm90cnVuYyksCgkJCQkJICBjb25zdF9iaW5vcCAoTVVMVF9FWFBSLAoJCQkJCQkgICAgICAgaTEsIHIyLCBub3RydW5jKSwKCQkJCQkgIG5vdHJ1bmMpKTsKCSAgYnJlYWs7CgoJY2FzZSBSRElWX0VYUFI6CgkgIHsKCSAgICB0cmVlIG1hZ3NxdWFyZWQKCSAgICAgID0gY29uc3RfYmlub3AgKFBMVVNfRVhQUiwKCQkJICAgICBjb25zdF9iaW5vcCAoTVVMVF9FWFBSLCByMiwgcjIsIG5vdHJ1bmMpLAoJCQkgICAgIGNvbnN0X2Jpbm9wIChNVUxUX0VYUFIsIGkyLCBpMiwgbm90cnVuYyksCgkJCSAgICAgbm90cnVuYyk7CgoJICAgIHQgPSBidWlsZF9jb21wbGV4ICh0eXBlLAoJCQkgICAgICAgY29uc3RfYmlub3AKCQkJICAgICAgIChJTlRFR1JBTF9UWVBFX1AgKFRSRUVfVFlQRSAocjEpKQoJCQkJPyBUUlVOQ19ESVZfRVhQUiA6IFJESVZfRVhQUiwKCQkJCWNvbnN0X2Jpbm9wIChQTFVTX0VYUFIsCgkJCQkJICAgICBjb25zdF9iaW5vcCAoTVVMVF9FWFBSLCByMSwgcjIsCgkJCQkJCQkgIG5vdHJ1bmMpLAoJCQkJCSAgICAgY29uc3RfYmlub3AgKE1VTFRfRVhQUiwgaTEsIGkyLAoJCQkJCQkJICBub3RydW5jKSwKCQkJCQkgICAgIG5vdHJ1bmMpLAoJCQkJbWFnc3F1YXJlZCwgbm90cnVuYyksCgkJCSAgICAgICBjb25zdF9iaW5vcAoJCQkgICAgICAgKElOVEVHUkFMX1RZUEVfUCAoVFJFRV9UWVBFIChyMSkpCgkJCQk/IFRSVU5DX0RJVl9FWFBSIDogUkRJVl9FWFBSLAoJCQkJY29uc3RfYmlub3AgKE1JTlVTX0VYUFIsCgkJCQkJICAgICBjb25zdF9iaW5vcCAoTVVMVF9FWFBSLCBpMSwgcjIsCgkJCQkJCQkgIG5vdHJ1bmMpLAoJCQkJCSAgICAgY29uc3RfYmlub3AgKE1VTFRfRVhQUiwgcjEsIGkyLAoJCQkJCQkJICBub3RydW5jKSwKCQkJCQkgICAgIG5vdHJ1bmMpLAoJCQkJbWFnc3F1YXJlZCwgbm90cnVuYykpOwoJICB9CgkgIGJyZWFrOwoKCWRlZmF1bHQ6CgkgIGFib3J0ICgpOwoJfQogICAgICByZXR1cm4gdDsKICAgIH0KICByZXR1cm4gMDsKfQoKLyogVGhlc2UgYXJlIHRoZSBoYXNoIHRhYmxlIGZ1bmN0aW9ucyBmb3IgdGhlIGhhc2ggdGFibGUgb2YgSU5URUdFUl9DU1QKICAgbm9kZXMgb2YgYSBzaXpldHlwZS4gICovCgovKiBSZXR1cm4gdGhlIGhhc2ggY29kZSBjb2RlIFgsIGFuIElOVEVHRVJfQ1NULiAgKi8KCnN0YXRpYyBoYXNodmFsX3QKc2l6ZV9odGFiX2hhc2ggKGNvbnN0IHZvaWQgKngpCnsKICB0cmVlIHQgPSAodHJlZSkgeDsKCiAgcmV0dXJuIChUUkVFX0lOVF9DU1RfSElHSCAodCkgXiBUUkVFX0lOVF9DU1RfTE9XICh0KQoJICBeIGh0YWJfaGFzaF9wb2ludGVyIChUUkVFX1RZUEUgKHQpKQoJICBeIChUUkVFX09WRVJGTE9XICh0KSA8PCAyMCkpOwp9CgovKiBSZXR1cm4gbm9uemVybyBpZiB0aGUgdmFsdWUgcmVwcmVzZW50ZWQgYnkgKlggKGFuIElOVEVHRVJfQ1NUIHRyZWUgbm9kZSkKICAgaXMgdGhlIHNhbWUgYXMgdGhhdCBnaXZlbiBieSAqWSwgd2hpY2ggaXMgdGhlIHNhbWUuICAqLwoKc3RhdGljIGludApzaXplX2h0YWJfZXEgKGNvbnN0IHZvaWQgKngsIGNvbnN0IHZvaWQgKnkpCnsKICB0cmVlIHh0ID0gKHRyZWUpIHg7CiAgdHJlZSB5dCA9ICh0cmVlKSB5OwoKICByZXR1cm4gKFRSRUVfSU5UX0NTVF9ISUdIICh4dCkgPT0gVFJFRV9JTlRfQ1NUX0hJR0ggKHl0KQoJICAmJiBUUkVFX0lOVF9DU1RfTE9XICh4dCkgPT0gVFJFRV9JTlRfQ1NUX0xPVyAoeXQpCgkgICYmIFRSRUVfVFlQRSAoeHQpID09IFRSRUVfVFlQRSAoeXQpCgkgICYmIFRSRUVfT1ZFUkZMT1cgKHh0KSA9PSBUUkVFX09WRVJGTE9XICh5dCkpOwp9CgwKLyogUmV0dXJuIGFuIElOVEVHRVJfQ1NUIHdpdGggdmFsdWUgd2hvc2UgbG93LW9yZGVyIEhPU1RfQklUU19QRVJfV0lERV9JTlQKICAgYml0cyBhcmUgZ2l2ZW4gYnkgTlVNQkVSIGFuZCBvZiB0aGUgc2l6ZXR5cGUgcmVwcmVzZW50ZWQgYnkgS0lORC4gICovCgp0cmVlCnNpemVfaW50X3dpZGUgKEhPU1RfV0lERV9JTlQgbnVtYmVyLCBlbnVtIHNpemVfdHlwZV9raW5kIGtpbmQpCnsKICByZXR1cm4gc2l6ZV9pbnRfdHlwZV93aWRlIChudW1iZXIsIHNpemV0eXBlX3RhYlsoaW50KSBraW5kXSk7Cn0KCi8qIExpa2V3aXNlLCBidXQgdGhlIGRlc2lyZWQgdHlwZSBpcyBzcGVjaWZpZWQgZXhwbGljaXRseS4gICovCgpzdGF0aWMgR1RZICgoKSkgdHJlZSBuZXdfY29uc3Q7CnN0YXRpYyBHVFkgKChpZl9tYXJrZWQgKCJnZ2NfbWFya2VkX3AiKSwgcGFyYW1faXMgKHVuaW9uIHRyZWVfbm9kZSkpKQogICAgIGh0YWJfdCBzaXplX2h0YWI7Cgp0cmVlCnNpemVfaW50X3R5cGVfd2lkZSAoSE9TVF9XSURFX0lOVCBudW1iZXIsIHRyZWUgdHlwZSkKewogIHZvaWQgKipzbG90OwoKICBpZiAoc2l6ZV9odGFiID09IDApCiAgICB7CiAgICAgIHNpemVfaHRhYiA9IGh0YWJfY3JlYXRlX2dnYyAoMTAyNCwgc2l6ZV9odGFiX2hhc2gsIHNpemVfaHRhYl9lcSwgTlVMTCk7CiAgICAgIG5ld19jb25zdCA9IG1ha2Vfbm9kZSAoSU5URUdFUl9DU1QpOwogICAgfQoKICAvKiBBZGp1c3QgTkVXX0NPTlNUIHRvIGJlIHRoZSBjb25zdGFudCB3ZSB3YW50LiAgSWYgaXQncyBhbHJlYWR5IGluIHRoZQogICAgIGhhc2ggdGFibGUsIHdlIHJldHVybiB0aGUgdmFsdWUgZnJvbSB0aGUgaGFzaCB0YWJsZS4gIE90aGVyd2lzZSwgd2UKICAgICBwbGFjZSB0aGF0IGluIHRoZSBoYXNoIHRhYmxlIGFuZCBtYWtlIGEgbmV3IG5vZGUgZm9yIHRoZSBuZXh0IHRpbWUuICAqLwogIFRSRUVfSU5UX0NTVF9MT1cgKG5ld19jb25zdCkgPSBudW1iZXI7CiAgVFJFRV9JTlRfQ1NUX0hJR0ggKG5ld19jb25zdCkgPSBudW1iZXIgPCAwID8gLTEgOiAwOwogIFRSRUVfVFlQRSAobmV3X2NvbnN0KSA9IHR5cGU7CiAgVFJFRV9PVkVSRkxPVyAobmV3X2NvbnN0KSA9IFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKG5ld19jb25zdCkKICAgID0gZm9yY2VfZml0X3R5cGUgKG5ld19jb25zdCwgMCk7CgogIHNsb3QgPSBodGFiX2ZpbmRfc2xvdCAoc2l6ZV9odGFiLCBuZXdfY29uc3QsIElOU0VSVCk7CiAgaWYgKCpzbG90ID09IDApCiAgICB7CiAgICAgIHRyZWUgdCA9IG5ld19jb25zdDsKCiAgICAgICpzbG90ID0gbmV3X2NvbnN0OwogICAgICBuZXdfY29uc3QgPSBtYWtlX25vZGUgKElOVEVHRVJfQ1NUKTsKICAgICAgcmV0dXJuIHQ7CiAgICB9CiAgZWxzZQogICAgcmV0dXJuICh0cmVlKSAqc2xvdDsKfQoKLyogQ29tYmluZSBvcGVyYW5kcyBPUDEgYW5kIE9QMiB3aXRoIGFyaXRobWV0aWMgb3BlcmF0aW9uIENPREUuICBDT0RFCiAgIGlzIGEgdHJlZSBjb2RlLiAgVGhlIHR5cGUgb2YgdGhlIHJlc3VsdCBpcyB0YWtlbiBmcm9tIHRoZSBvcGVyYW5kcy4KICAgQm90aCBtdXN0IGJlIHRoZSBzYW1lIHR5cGUgaW50ZWdlciB0eXBlIGFuZCBpdCBtdXN0IGJlIGEgc2l6ZSB0eXBlLgogICBJZiB0aGUgb3BlcmFuZHMgYXJlIGNvbnN0YW50LCBzbyBpcyB0aGUgcmVzdWx0LiAgKi8KCnRyZWUKc2l6ZV9iaW5vcCAoZW51bSB0cmVlX2NvZGUgY29kZSwgdHJlZSBhcmcwLCB0cmVlIGFyZzEpCnsKICB0cmVlIHR5cGUgPSBUUkVFX1RZUEUgKGFyZzApOwoKICBpZiAoVFJFRV9DT0RFICh0eXBlKSAhPSBJTlRFR0VSX1RZUEUgfHwgISBUWVBFX0lTX1NJWkVUWVBFICh0eXBlKQogICAgICB8fCB0eXBlICE9IFRSRUVfVFlQRSAoYXJnMSkpCiAgICBhYm9ydCAoKTsKCiAgLyogSGFuZGxlIHRoZSBzcGVjaWFsIGNhc2Ugb2YgdHdvIGludGVnZXIgY29uc3RhbnRzIGZhc3Rlci4gICovCiAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gSU5URUdFUl9DU1QgJiYgVFJFRV9DT0RFIChhcmcxKSA9PSBJTlRFR0VSX0NTVCkKICAgIHsKICAgICAgLyogQW5kIHNvbWUgc3BlY2lmaWMgY2FzZXMgZXZlbiBmYXN0ZXIgdGhhbiB0aGF0LiAgKi8KICAgICAgaWYgKGNvZGUgPT0gUExVU19FWFBSICYmIGludGVnZXJfemVyb3AgKGFyZzApKQoJcmV0dXJuIGFyZzE7CiAgICAgIGVsc2UgaWYgKChjb2RlID09IE1JTlVTX0VYUFIgfHwgY29kZSA9PSBQTFVTX0VYUFIpCgkgICAgICAgJiYgaW50ZWdlcl96ZXJvcCAoYXJnMSkpCglyZXR1cm4gYXJnMDsKICAgICAgZWxzZSBpZiAoY29kZSA9PSBNVUxUX0VYUFIgJiYgaW50ZWdlcl9vbmVwIChhcmcwKSkKCXJldHVybiBhcmcxOwoKICAgICAgLyogSGFuZGxlIGdlbmVyYWwgY2FzZSBvZiB0d28gaW50ZWdlciBjb25zdGFudHMuICAqLwogICAgICByZXR1cm4gaW50X2NvbnN0X2Jpbm9wIChjb2RlLCBhcmcwLCBhcmcxLCAwKTsKICAgIH0KCiAgaWYgKGFyZzAgPT0gZXJyb3JfbWFya19ub2RlIHx8IGFyZzEgPT0gZXJyb3JfbWFya19ub2RlKQogICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCiAgcmV0dXJuIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLCBhcmcwLCBhcmcxKSk7Cn0KCi8qIEdpdmVuIHR3byB2YWx1ZXMsIGVpdGhlciBib3RoIG9mIHNpemV0eXBlIG9yIGJvdGggb2YgYml0c2l6ZXR5cGUsCiAgIGNvbXB1dGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIHZhbHVlcy4gIFJldHVybiB0aGUgdmFsdWUKICAgaW4gc2lnbmVkIHR5cGUgY29ycmVzcG9uZGluZyB0byB0aGUgdHlwZSBvZiB0aGUgb3BlcmFuZHMuICAqLwoKdHJlZQpzaXplX2RpZmZvcCAodHJlZSBhcmcwLCB0cmVlIGFyZzEpCnsKICB0cmVlIHR5cGUgPSBUUkVFX1RZUEUgKGFyZzApOwogIHRyZWUgY3R5cGU7CgogIGlmIChUUkVFX0NPREUgKHR5cGUpICE9IElOVEVHRVJfVFlQRSB8fCAhIFRZUEVfSVNfU0laRVRZUEUgKHR5cGUpCiAgICAgIHx8IHR5cGUgIT0gVFJFRV9UWVBFIChhcmcxKSkKICAgIGFib3J0ICgpOwoKICAvKiBJZiB0aGUgdHlwZSBpcyBhbHJlYWR5IHNpZ25lZCwganVzdCBkbyB0aGUgc2ltcGxlIHRoaW5nLiAgKi8KICBpZiAoISBUUkVFX1VOU0lHTkVEICh0eXBlKSkKICAgIHJldHVybiBzaXplX2Jpbm9wIChNSU5VU19FWFBSLCBhcmcwLCBhcmcxKTsKCiAgY3R5cGUgPSAodHlwZSA9PSBiaXRzaXpldHlwZSB8fCB0eXBlID09IHViaXRzaXpldHlwZQoJICAgPyBzYml0c2l6ZXR5cGUgOiBzc2l6ZXR5cGUpOwoKICAvKiBJZiBlaXRoZXIgb3BlcmFuZCBpcyBub3QgYSBjb25zdGFudCwgZG8gdGhlIGNvbnZlcnNpb25zIHRvIHRoZSBzaWduZWQKICAgICB0eXBlIGFuZCBzdWJ0cmFjdC4gIFRoZSBoYXJkd2FyZSB3aWxsIGRvIHRoZSByaWdodCB0aGluZyB3aXRoIGFueQogICAgIG92ZXJmbG93IGluIHRoZSBzdWJ0cmFjdGlvbi4gICovCiAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgIT0gSU5URUdFUl9DU1QgfHwgVFJFRV9DT0RFIChhcmcxKSAhPSBJTlRFR0VSX0NTVCkKICAgIHJldHVybiBzaXplX2Jpbm9wIChNSU5VU19FWFBSLCBmb2xkX2NvbnZlcnQgKGN0eXBlLCBhcmcwKSwKCQkgICAgICAgZm9sZF9jb252ZXJ0IChjdHlwZSwgYXJnMSkpOwoKICAvKiBJZiBBUkcwIGlzIGxhcmdlciB0aGFuIEFSRzEsIHN1YnRyYWN0IGFuZCByZXR1cm4gdGhlIHJlc3VsdCBpbiBDVFlQRS4KICAgICBPdGhlcndpc2UsIHN1YnRyYWN0IHRoZSBvdGhlciB3YXksIGNvbnZlcnQgdG8gQ1RZUEUgKHdlIGtub3cgdGhhdCBjYW4ndAogICAgIG92ZXJmbG93KSBhbmQgbmVnYXRlICh3aGljaCBjYW4ndCBlaXRoZXIpLiAgU3BlY2lhbC1jYXNlIGEgcmVzdWx0CiAgICAgb2YgemVybyB3aGlsZSB3ZSdyZSBoZXJlLiAgKi8KICBpZiAodHJlZV9pbnRfY3N0X2VxdWFsIChhcmcwLCBhcmcxKSkKICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKGN0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSk7CiAgZWxzZSBpZiAodHJlZV9pbnRfY3N0X2x0IChhcmcxLCBhcmcwKSkKICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKGN0eXBlLCBzaXplX2Jpbm9wIChNSU5VU19FWFBSLCBhcmcwLCBhcmcxKSk7CiAgZWxzZQogICAgcmV0dXJuIHNpemVfYmlub3AgKE1JTlVTX0VYUFIsIGZvbGRfY29udmVydCAoY3R5cGUsIGludGVnZXJfemVyb19ub2RlKSwKCQkgICAgICAgZm9sZF9jb252ZXJ0IChjdHlwZSwgc2l6ZV9iaW5vcCAoTUlOVVNfRVhQUiwKCQkJCQkJCWFyZzEsIGFyZzApKSk7Cn0KDAoKLyogQXR0ZW1wdCB0byBmb2xkIHR5cGUgY29udmVyc2lvbiBvcGVyYXRpb24gQ09ERSBvZiBleHByZXNzaW9uIEFSRzEgdG8KICAgdHlwZSBUWVBFLiAgSWYgbm8gc2ltcGxpZmljYXRpb24gY2FuIGJlIGRvbmUgcmV0dXJuIE5VTExfVFJFRS4gICovCgpzdGF0aWMgdHJlZQpmb2xkX2NvbnZlcnRfY29uc3QgKGVudW0gdHJlZV9jb2RlIGNvZGUgQVRUUklCVVRFX1VOVVNFRCwgdHJlZSB0eXBlLAoJCSAgICB0cmVlIGFyZzEpCnsKICBpbnQgb3ZlcmZsb3cgPSAwOwogIHRyZWUgdDsKCiAgaWYgKFRSRUVfVFlQRSAoYXJnMSkgPT0gdHlwZSkKICAgIHJldHVybiBhcmcxOwoKICBpZiAoUE9JTlRFUl9UWVBFX1AgKHR5cGUpIHx8IElOVEVHUkFMX1RZUEVfUCAodHlwZSkpCiAgICB7CiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUKQoJewoJICAvKiBJZiB3ZSB3b3VsZCBidWlsZCBhIGNvbnN0YW50IHdpZGVyIHRoYW4gR0NDIHN1cHBvcnRzLAoJICAgICBsZWF2ZSB0aGUgY29udmVyc2lvbiB1bmZvbGRlZC4gICovCgkgIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPiAyICogSE9TVF9CSVRTX1BFUl9XSURFX0lOVCkKCSAgICByZXR1cm4gTlVMTF9UUkVFOwoKCSAgLyogSWYgd2UgYXJlIHRyeWluZyB0byBtYWtlIGEgc2l6ZXR5cGUgZm9yIGEgc21hbGwgaW50ZWdlciwgdXNlCgkgICAgIHNpemVfaW50IHRvIHBpY2sgdXAgY2FjaGVkIHR5cGVzIHRvIHJlZHVjZSBkdXBsaWNhdGUgbm9kZXMuICAqLwoJICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBJTlRFR0VSX1RZUEUgJiYgVFlQRV9JU19TSVpFVFlQRSAodHlwZSkKCSAgICAgICYmICFUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcxKQoJICAgICAgJiYgY29tcGFyZV90cmVlX2ludCAoYXJnMSwgMTAwMDApIDwgMCkKCSAgICByZXR1cm4gc2l6ZV9pbnRfdHlwZV93aWRlIChUUkVFX0lOVF9DU1RfTE9XIChhcmcxKSwgdHlwZSk7CgoJICAvKiBHaXZlbiBhbiBpbnRlZ2VyIGNvbnN0YW50LCBtYWtlIG5ldyBjb25zdGFudCB3aXRoIG5ldyB0eXBlLAoJICAgICBhcHByb3ByaWF0ZWx5IHNpZ24tZXh0ZW5kZWQgb3IgdHJ1bmNhdGVkLiAgKi8KCSAgdCA9IGJ1aWxkX2ludF8yIChUUkVFX0lOVF9DU1RfTE9XIChhcmcxKSwKCQkJICAgVFJFRV9JTlRfQ1NUX0hJR0ggKGFyZzEpKTsKCSAgVFJFRV9UWVBFICh0KSA9IHR5cGU7CgkgIC8qIEluZGljYXRlIGFuIG92ZXJmbG93IGlmICgxKSBBUkcxIGFscmVhZHkgb3ZlcmZsb3dlZCwKCSAgICAgb3IgKDIpIGZvcmNlX2ZpdF90eXBlIGluZGljYXRlcyBhbiBvdmVyZmxvdy4KCSAgICAgVGVsbCBmb3JjZV9maXRfdHlwZSB0aGF0IGFuIG92ZXJmbG93IGhhcyBhbHJlYWR5IG9jY3VycmVkCgkgICAgIGlmIEFSRzEgaXMgYSB0b28tbGFyZ2UgdW5zaWduZWQgdmFsdWUgYW5kIFQgaXMgc2lnbmVkLgoJICAgICBCdXQgZG9uJ3QgaW5kaWNhdGUgYW4gb3ZlcmZsb3cgaWYgY29udmVydGluZyBhIHBvaW50ZXIuICAqLwoJICBUUkVFX09WRVJGTE9XICh0KQoJICAgID0gKChmb3JjZV9maXRfdHlwZSAodCwKCQkJCShUUkVFX0lOVF9DU1RfSElHSCAoYXJnMSkgPCAwCgkJCQkgJiYgKFRSRUVfVU5TSUdORUQgKHR5cGUpCgkJCQkgICAgPCBUUkVFX1VOU0lHTkVEIChUUkVFX1RZUEUgKGFyZzEpKSkpKQoJCSYmICEgUE9JTlRFUl9UWVBFX1AgKFRSRUVfVFlQRSAoYXJnMSkpKQoJICAgICAgIHx8IFRSRUVfT1ZFUkZMT1cgKGFyZzEpKTsKCSAgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAodCkKCSAgICA9IFRSRUVfT1ZFUkZMT1cgKHQpIHwgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAoYXJnMSk7CgkgIHJldHVybiB0OwoJfQogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKGFyZzEpID09IFJFQUxfQ1NUKQoJewoJICAvKiBUaGUgZm9sbG93aW5nIGNvZGUgaW1wbGVtZW50cyB0aGUgZmxvYXRpbmcgcG9pbnQgdG8gaW50ZWdlcgoJICAgICBjb252ZXJzaW9uIHJ1bGVzIHJlcXVpcmVkIGJ5IHRoZSBKYXZhIExhbmd1YWdlIFNwZWNpZmljYXRpb24sCgkgICAgIHRoYXQgSUVFRSBOYU5zIGFyZSBtYXBwZWQgdG8gemVybyBhbmQgdmFsdWVzIHRoYXQgb3ZlcmZsb3cKCSAgICAgdGhlIHRhcmdldCBwcmVjaXNpb24gc2F0dXJhdGUsIGkuZS4gdmFsdWVzIGdyZWF0ZXIgdGhhbgoJICAgICBJTlRfTUFYIGFyZSBtYXBwZWQgdG8gSU5UX01BWCwgYW5kIHZhbHVlcyBsZXNzIHRoYW4gSU5UX01JTgoJICAgICBhcmUgbWFwcGVkIHRvIElOVF9NSU4uICBUaGVzZSBzZW1hbnRpY3MgYXJlIGFsbG93ZWQgYnkgdGhlCgkgICAgIEMgYW5kIEMrKyBzdGFuZGFyZHMgdGhhdCBzaW1wbHkgc3RhdGUgdGhhdCB0aGUgYmVoYXZpb3Igb2YKCSAgICAgRlAtdG8taW50ZWdlciBjb252ZXJzaW9uIGlzIHVuc3BlY2lmaWVkIHVwb24gb3ZlcmZsb3cuICAqLwoKCSAgSE9TVF9XSURFX0lOVCBoaWdoLCBsb3c7CgoJICBSRUFMX1ZBTFVFX1RZUEUgeCA9IFRSRUVfUkVBTF9DU1QgKGFyZzEpOwoJICAvKiBJZiB4IGlzIE5hTiwgcmV0dXJuIHplcm8gYW5kIHNob3cgd2UgaGF2ZSBhbiBvdmVyZmxvdy4gICovCgkgIGlmIChSRUFMX1ZBTFVFX0lTTkFOICh4KSkKCSAgICB7CgkgICAgICBvdmVyZmxvdyA9IDE7CgkgICAgICBoaWdoID0gMDsKCSAgICAgIGxvdyA9IDA7CgkgICAgfQoKCSAgLyogU2VlIGlmIFggd2lsbCBiZSBpbiByYW5nZSBhZnRlciB0cnVuY2F0aW9uIHRvd2FyZHMgMC4KCSAgICAgVG8gY29tcGVuc2F0ZSBmb3IgdHJ1bmNhdGlvbiwgbW92ZSB0aGUgYm91bmRzIGF3YXkgZnJvbSAwLAoJICAgICBidXQgcmVqZWN0IGlmIFggZXhhY3RseSBlcXVhbHMgdGhlIGFkanVzdGVkIGJvdW5kcy4gICovCgoJICBpZiAoISBvdmVyZmxvdykKCSAgICB7CgkgICAgICB0cmVlIGx0ID0gVFlQRV9NSU5fVkFMVUUgKHR5cGUpOwoJICAgICAgUkVBTF9WQUxVRV9UWVBFIGwgPSByZWFsX3ZhbHVlX2Zyb21faW50X2NzdCAoTlVMTF9UUkVFLCBsdCk7CgkgICAgICBSRUFMX0FSSVRITUVUSUMgKGwsIE1JTlVTX0VYUFIsIGwsIGRjb25zdDEpOwoJICAgICAgaWYgKCEgUkVBTF9WQUxVRVNfTEVTUyAobCwgeCkpCgkJewoJCSAgb3ZlcmZsb3cgPSAxOwoJCSAgaGlnaCA9IFRSRUVfSU5UX0NTVF9ISUdIIChsdCk7CgkJICBsb3cgPSBUUkVFX0lOVF9DU1RfTE9XIChsdCk7CgkJfQoJICAgIH0KCgkgIGlmICghIG92ZXJmbG93KQoJICAgIHsKCSAgICAgIHRyZWUgdXQgPSBUWVBFX01BWF9WQUxVRSAodHlwZSk7CgkgICAgICBpZiAodXQpCgkJewoJCSAgUkVBTF9WQUxVRV9UWVBFIHUgPSByZWFsX3ZhbHVlX2Zyb21faW50X2NzdCAoTlVMTF9UUkVFLCB1dCk7CgkJICBSRUFMX0FSSVRITUVUSUMgKHUsIFBMVVNfRVhQUiwgdSwgZGNvbnN0MSk7CgkJICBpZiAoISBSRUFMX1ZBTFVFU19MRVNTICh4LCB1KSkKCQkgICAgewoJCSAgICAgIG92ZXJmbG93ID0gMTsKCQkgICAgICBoaWdoID0gVFJFRV9JTlRfQ1NUX0hJR0ggKHV0KTsKCQkgICAgICBsb3cgPSBUUkVFX0lOVF9DU1RfTE9XICh1dCk7CgkJICAgIH0KCQl9CgkgICAgfQoKCSAgaWYgKCEgb3ZlcmZsb3cpCgkgICAgUkVBTF9WQUxVRV9UT19JTlQgKCZsb3csICZoaWdoLCB4KTsKCgkgIHQgPSBidWlsZF9pbnRfMiAobG93LCBoaWdoKTsKCSAgVFJFRV9UWVBFICh0KSA9IHR5cGU7CgkgIFRSRUVfT1ZFUkZMT1cgKHQpCgkgICAgPSBUUkVFX09WRVJGTE9XIChhcmcxKSB8IGZvcmNlX2ZpdF90eXBlICh0LCBvdmVyZmxvdyk7CgkgIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKHQpCgkgICAgPSBUUkVFX09WRVJGTE9XICh0KSB8IFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKGFyZzEpOwoJICByZXR1cm4gdDsKCX0KICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpID09IFJFQUxfVFlQRSkKICAgIHsKICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QpCglyZXR1cm4gYnVpbGRfcmVhbF9mcm9tX2ludF9jc3QgKHR5cGUsIGFyZzEpOwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBSRUFMX0NTVCkKCXsKCSAgaWYgKFJFQUxfVkFMVUVfSVNOQU4gKFRSRUVfUkVBTF9DU1QgKGFyZzEpKSkKCSAgICB7CgkgICAgICAvKiBXZSBtYWtlIGEgY29weSBvZiBBUkcxIHNvIHRoYXQgd2UgZG9uJ3QgbW9kaWZ5IGFuCgkJIGV4aXN0aW5nIGNvbnN0YW50IHRyZWUuICAqLwoJICAgICAgdCA9IGNvcHlfbm9kZSAoYXJnMSk7CgkgICAgICBUUkVFX1RZUEUgKHQpID0gdHlwZTsKCSAgICAgIHJldHVybiB0OwoJICAgIH0KCgkgIHQgPSBidWlsZF9yZWFsICh0eXBlLAoJCQkgIHJlYWxfdmFsdWVfdHJ1bmNhdGUgKFRZUEVfTU9ERSAodHlwZSksCgkJCQkJICAgICAgIFRSRUVfUkVBTF9DU1QgKGFyZzEpKSk7CgoJICBUUkVFX09WRVJGTE9XICh0KQoJICAgID0gVFJFRV9PVkVSRkxPVyAoYXJnMSkgfCBmb3JjZV9maXRfdHlwZSAodCwgMCk7CgkgIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKHQpCgkgICAgPSBUUkVFX09WRVJGTE9XICh0KSB8IFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKGFyZzEpOwoJICByZXR1cm4gdDsKCX0KICAgIH0KICByZXR1cm4gTlVMTF9UUkVFOwp9CgovKiBDb252ZXJ0IGV4cHJlc3Npb24gQVJHIHRvIHR5cGUgVFlQRS4gIFVzZWQgYnkgdGhlIG1pZGRsZS1lbmQgZm9yCiAgIHNpbXBsZSBjb252ZXJzaW9ucyBpbiBwcmVmZXJlbmNlIHRvIGNhbGxpbmcgdGhlIGZyb250LWVuZCdzIGNvbnZlcnQuICAqLwoKc3RhdGljIHRyZWUKZm9sZF9jb252ZXJ0ICh0cmVlIHR5cGUsIHRyZWUgYXJnKQp7CiAgdHJlZSBvcmlnID0gVFJFRV9UWVBFIChhcmcpOwogIHRyZWUgdGVtOwoKICBpZiAodHlwZSA9PSBvcmlnKQogICAgcmV0dXJuIGFyZzsKCiAgaWYgKFRSRUVfQ09ERSAoYXJnKSA9PSBFUlJPUl9NQVJLCiAgICAgIHx8IFRSRUVfQ09ERSAodHlwZSkgPT0gRVJST1JfTUFSSwogICAgICB8fCBUUkVFX0NPREUgKG9yaWcpID09IEVSUk9SX01BUkspCiAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICBpZiAoVFlQRV9NQUlOX1ZBUklBTlQgKHR5cGUpID09IFRZUEVfTUFJTl9WQVJJQU5UIChvcmlnKSkKICAgIHJldHVybiBmb2xkIChidWlsZDEgKE5PUF9FWFBSLCB0eXBlLCBhcmcpKTsKCiAgaWYgKElOVEVHUkFMX1RZUEVfUCAodHlwZSkgfHwgUE9JTlRFUl9UWVBFX1AgKHR5cGUpKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFIChhcmcpID09IElOVEVHRVJfQ1NUKQoJewoJICB0ZW0gPSBmb2xkX2NvbnZlcnRfY29uc3QgKE5PUF9FWFBSLCB0eXBlLCBhcmcpOwoJICBpZiAodGVtICE9IE5VTExfVFJFRSkKCSAgICByZXR1cm4gdGVtOwoJfQogICAgICBpZiAoSU5URUdSQUxfVFlQRV9QIChvcmlnKSB8fCBQT0lOVEVSX1RZUEVfUCAob3JpZykpCiAgICAgICAgcmV0dXJuIGZvbGQgKGJ1aWxkMSAoTk9QX0VYUFIsIHR5cGUsIGFyZykpOwogICAgICBpZiAoVFJFRV9DT0RFIChvcmlnKSA9PSBDT01QTEVYX1RZUEUpCgl7CgkgIHRlbSA9IGZvbGQgKGJ1aWxkMSAoUkVBTFBBUlRfRVhQUiwgVFJFRV9UWVBFIChvcmlnKSwgYXJnKSk7CgkgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIHRlbSk7Cgl9CiAgICAgIGlmIChUUkVFX0NPREUgKG9yaWcpID09IFZFQ1RPUl9UWVBFCgkgICYmIEdFVF9NT0RFX1NJWkUgKFRZUEVfTU9ERSAodHlwZSkpCgkgICAgID09IEdFVF9NT0RFX1NJWkUgKFRZUEVfTU9ERSAob3JpZykpKQoJcmV0dXJuIGZvbGQgKGJ1aWxkMSAoTk9QX0VYUFIsIHR5cGUsIGFyZykpOwogICAgfQogIGVsc2UgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gUkVBTF9UWVBFKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFIChhcmcpID09IElOVEVHRVJfQ1NUKQoJewoJICB0ZW0gPSBmb2xkX2NvbnZlcnRfY29uc3QgKEZMT0FUX0VYUFIsIHR5cGUsIGFyZyk7CgkgIGlmICh0ZW0gIT0gTlVMTF9UUkVFKQoJICAgIHJldHVybiB0ZW07Cgl9CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnKSA9PSBSRUFMX0NTVCkKCXsKCSAgdGVtID0gZm9sZF9jb252ZXJ0X2NvbnN0IChOT1BfRVhQUiwgdHlwZSwgYXJnKTsKCSAgaWYgKHRlbSAhPSBOVUxMX1RSRUUpCgkgICAgcmV0dXJuIHRlbTsKCX0KCiAgICAgIGlmIChJTlRFR1JBTF9UWVBFX1AgKG9yaWcpIHx8IFBPSU5URVJfVFlQRV9QIChvcmlnKSkKICAgICAgICByZXR1cm4gZm9sZCAoYnVpbGQxIChGTE9BVF9FWFBSLCB0eXBlLCBhcmcpKTsKICAgICAgaWYgKFRSRUVfQ09ERSAob3JpZykgPT0gUkVBTF9UWVBFKQoJcmV0dXJuIGZvbGQgKGJ1aWxkMSAoZmxhZ19mbG9hdF9zdG9yZSA/IENPTlZFUlRfRVhQUiA6IE5PUF9FWFBSLAoJCQkgICAgIHR5cGUsIGFyZykpOwogICAgICBpZiAoVFJFRV9DT0RFIChvcmlnKSA9PSBDT01QTEVYX1RZUEUpCgl7CgkgIHRlbSA9IGZvbGQgKGJ1aWxkMSAoUkVBTFBBUlRfRVhQUiwgVFJFRV9UWVBFIChvcmlnKSwgYXJnKSk7CgkgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIHRlbSk7Cgl9CiAgICB9CiAgZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBDT01QTEVYX1RZUEUpCiAgICB7CiAgICAgIGlmIChJTlRFR1JBTF9UWVBFX1AgKG9yaWcpCgkgIHx8IFBPSU5URVJfVFlQRV9QIChvcmlnKQoJICB8fCBUUkVFX0NPREUgKG9yaWcpID09IFJFQUxfVFlQRSkKCXJldHVybiBidWlsZCAoQ09NUExFWF9FWFBSLCB0eXBlLAoJCSAgICAgIGZvbGRfY29udmVydCAoVFJFRV9UWVBFICh0eXBlKSwgYXJnKSwKCQkgICAgICBmb2xkX2NvbnZlcnQgKFRSRUVfVFlQRSAodHlwZSksIGludGVnZXJfemVyb19ub2RlKSk7CiAgICAgIGlmIChUUkVFX0NPREUgKG9yaWcpID09IENPTVBMRVhfVFlQRSkKCXsKCSAgdHJlZSBycGFydCwgaXBhcnQ7CgoJICBpZiAoVFJFRV9DT0RFIChhcmcpID09IENPTVBMRVhfRVhQUikKCSAgICB7CgkgICAgICBycGFydCA9IGZvbGRfY29udmVydCAoVFJFRV9UWVBFICh0eXBlKSwgVFJFRV9PUEVSQU5EIChhcmcsIDApKTsKCSAgICAgIGlwYXJ0ID0gZm9sZF9jb252ZXJ0IChUUkVFX1RZUEUgKHR5cGUpLCBUUkVFX09QRVJBTkQgKGFyZywgMSkpOwoJICAgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChDT01QTEVYX0VYUFIsIHR5cGUsIHJwYXJ0LCBpcGFydCkpOwoJICAgIH0KCgkgIGFyZyA9IHNhdmVfZXhwciAoYXJnKTsKCSAgcnBhcnQgPSBmb2xkIChidWlsZDEgKFJFQUxQQVJUX0VYUFIsIFRSRUVfVFlQRSAob3JpZyksIGFyZykpOwoJICBpcGFydCA9IGZvbGQgKGJ1aWxkMSAoSU1BR1BBUlRfRVhQUiwgVFJFRV9UWVBFIChvcmlnKSwgYXJnKSk7CgkgIHJwYXJ0ID0gZm9sZF9jb252ZXJ0IChUUkVFX1RZUEUgKHR5cGUpLCBycGFydCk7CgkgIGlwYXJ0ID0gZm9sZF9jb252ZXJ0IChUUkVFX1RZUEUgKHR5cGUpLCBpcGFydCk7CgkgIHJldHVybiBmb2xkIChidWlsZCAoQ09NUExFWF9FWFBSLCB0eXBlLCBycGFydCwgaXBhcnQpKTsKCX0KICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpID09IFZFQ1RPUl9UWVBFKQogICAgewogICAgICBpZiAoKElOVEVHUkFMX1RZUEVfUCAob3JpZykgfHwgUE9JTlRFUl9UWVBFX1AgKG9yaWcpKQoJICAmJiBHRVRfTU9ERV9TSVpFIChUWVBFX01PREUgKHR5cGUpKQoJICAgICA9PSBHRVRfTU9ERV9TSVpFIChUWVBFX01PREUgKG9yaWcpKSkKCXJldHVybiBmb2xkIChidWlsZDEgKE5PUF9FWFBSLCB0eXBlLCBhcmcpKTsKICAgICAgaWYgKFRSRUVfQ09ERSAob3JpZykgPT0gVkVDVE9SX1RZUEUKCSAgJiYgR0VUX01PREVfU0laRSAoVFlQRV9NT0RFICh0eXBlKSkKCSAgICAgPT0gR0VUX01PREVfU0laRSAoVFlQRV9NT0RFIChvcmlnKSkpCglyZXR1cm4gZm9sZCAoYnVpbGQxIChOT1BfRVhQUiwgdHlwZSwgYXJnKSk7CiAgICB9CiAgZWxzZSBpZiAoVk9JRF9UWVBFX1AgKHR5cGUpKQogICAgcmV0dXJuIGZvbGQgKGJ1aWxkMSAoQ09OVkVSVF9FWFBSLCB0eXBlLCBhcmcpKTsKICBhYm9ydCAoKTsKfQoMCi8qIFJldHVybiBhbiBleHByIGVxdWFsIHRvIFggYnV0IGNlcnRhaW5seSBub3QgdmFsaWQgYXMgYW4gbHZhbHVlLiAgKi8KCnRyZWUKbm9uX2x2YWx1ZSAodHJlZSB4KQp7CiAgdHJlZSByZXN1bHQ7CgogIC8qIFRoZXNlIHRoaW5ncyBhcmUgY2VydGFpbmx5IG5vdCBsdmFsdWVzLiAgKi8KICBpZiAoVFJFRV9DT0RFICh4KSA9PSBOT05fTFZBTFVFX0VYUFIKICAgICAgfHwgVFJFRV9DT0RFICh4KSA9PSBJTlRFR0VSX0NTVAogICAgICB8fCBUUkVFX0NPREUgKHgpID09IFJFQUxfQ1NUCiAgICAgIHx8IFRSRUVfQ09ERSAoeCkgPT0gU1RSSU5HX0NTVAogICAgICB8fCBUUkVFX0NPREUgKHgpID09IEFERFJfRVhQUikKICAgIHJldHVybiB4OwoKICByZXN1bHQgPSBidWlsZDEgKE5PTl9MVkFMVUVfRVhQUiwgVFJFRV9UWVBFICh4KSwgeCk7CiAgVFJFRV9DT05TVEFOVCAocmVzdWx0KSA9IFRSRUVfQ09OU1RBTlQgKHgpOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qIE5vbnplcm8gbWVhbnMgbHZhbHVlcyBhcmUgbGltaXRlZCB0byB0aG9zZSB2YWxpZCBpbiBwZWRhbnRpYyBBTlNJIEMuCiAgIFplcm8gbWVhbnMgYWxsb3cgZXh0ZW5kZWQgbHZhbHVlcy4gICovCgppbnQgcGVkYW50aWNfbHZhbHVlczsKCi8qIFdoZW4gcGVkYW50aWMsIHJldHVybiBhbiBleHByIGVxdWFsIHRvIFggYnV0IGNlcnRhaW5seSBub3QgdmFsaWQgYXMgYQogICBwZWRhbnRpYyBsdmFsdWUuICBPdGhlcndpc2UsIHJldHVybiBYLiAgKi8KCnRyZWUKcGVkYW50aWNfbm9uX2x2YWx1ZSAodHJlZSB4KQp7CiAgaWYgKHBlZGFudGljX2x2YWx1ZXMpCiAgICByZXR1cm4gbm9uX2x2YWx1ZSAoeCk7CiAgZWxzZQogICAgcmV0dXJuIHg7Cn0KDAovKiBHaXZlbiBhIHRyZWUgY29tcGFyaXNvbiBjb2RlLCByZXR1cm4gdGhlIGNvZGUgdGhhdCBpcyB0aGUgbG9naWNhbCBpbnZlcnNlCiAgIG9mIHRoZSBnaXZlbiBjb2RlLiAgSXQgaXMgbm90IHNhZmUgdG8gZG8gdGhpcyBmb3IgZmxvYXRpbmctcG9pbnQKICAgY29tcGFyaXNvbnMsIGV4Y2VwdCBmb3IgTkVfRVhQUiBhbmQgRVFfRVhQUi4gICovCgpzdGF0aWMgZW51bSB0cmVlX2NvZGUKaW52ZXJ0X3RyZWVfY29tcGFyaXNvbiAoZW51bSB0cmVlX2NvZGUgY29kZSkKewogIHN3aXRjaCAoY29kZSkKICAgIHsKICAgIGNhc2UgRVFfRVhQUjoKICAgICAgcmV0dXJuIE5FX0VYUFI7CiAgICBjYXNlIE5FX0VYUFI6CiAgICAgIHJldHVybiBFUV9FWFBSOwogICAgY2FzZSBHVF9FWFBSOgogICAgICByZXR1cm4gTEVfRVhQUjsKICAgIGNhc2UgR0VfRVhQUjoKICAgICAgcmV0dXJuIExUX0VYUFI7CiAgICBjYXNlIExUX0VYUFI6CiAgICAgIHJldHVybiBHRV9FWFBSOwogICAgY2FzZSBMRV9FWFBSOgogICAgICByZXR1cm4gR1RfRVhQUjsKICAgIGRlZmF1bHQ6CiAgICAgIGFib3J0ICgpOwogICAgfQp9CgovKiBTaW1pbGFyLCBidXQgcmV0dXJuIHRoZSBjb21wYXJpc29uIHRoYXQgcmVzdWx0cyBpZiB0aGUgb3BlcmFuZHMgYXJlCiAgIHN3YXBwZWQuICBUaGlzIGlzIHNhZmUgZm9yIGZsb2F0aW5nLXBvaW50LiAgKi8KCnN0YXRpYyBlbnVtIHRyZWVfY29kZQpzd2FwX3RyZWVfY29tcGFyaXNvbiAoZW51bSB0cmVlX2NvZGUgY29kZSkKewogIHN3aXRjaCAoY29kZSkKICAgIHsKICAgIGNhc2UgRVFfRVhQUjoKICAgIGNhc2UgTkVfRVhQUjoKICAgICAgcmV0dXJuIGNvZGU7CiAgICBjYXNlIEdUX0VYUFI6CiAgICAgIHJldHVybiBMVF9FWFBSOwogICAgY2FzZSBHRV9FWFBSOgogICAgICByZXR1cm4gTEVfRVhQUjsKICAgIGNhc2UgTFRfRVhQUjoKICAgICAgcmV0dXJuIEdUX0VYUFI7CiAgICBjYXNlIExFX0VYUFI6CiAgICAgIHJldHVybiBHRV9FWFBSOwogICAgZGVmYXVsdDoKICAgICAgYWJvcnQgKCk7CiAgICB9Cn0KCgovKiBDb252ZXJ0IGEgY29tcGFyaXNvbiB0cmVlIGNvZGUgZnJvbSBhbiBlbnVtIHRyZWVfY29kZSByZXByZXNlbnRhdGlvbgogICBpbnRvIGEgY29tcGNvZGUgYml0LWJhc2VkIGVuY29kaW5nLiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgaW52ZXJzZSBvZgogICBjb21wY29kZV90b19jb21wYXJpc29uLiAgKi8KCnN0YXRpYyBpbnQKY29tcGFyaXNvbl90b19jb21wY29kZSAoZW51bSB0cmVlX2NvZGUgY29kZSkKewogIHN3aXRjaCAoY29kZSkKICAgIHsKICAgIGNhc2UgTFRfRVhQUjoKICAgICAgcmV0dXJuIENPTVBDT0RFX0xUOwogICAgY2FzZSBFUV9FWFBSOgogICAgICByZXR1cm4gQ09NUENPREVfRVE7CiAgICBjYXNlIExFX0VYUFI6CiAgICAgIHJldHVybiBDT01QQ09ERV9MRTsKICAgIGNhc2UgR1RfRVhQUjoKICAgICAgcmV0dXJuIENPTVBDT0RFX0dUOwogICAgY2FzZSBORV9FWFBSOgogICAgICByZXR1cm4gQ09NUENPREVfTkU7CiAgICBjYXNlIEdFX0VYUFI6CiAgICAgIHJldHVybiBDT01QQ09ERV9HRTsKICAgIGRlZmF1bHQ6CiAgICAgIGFib3J0ICgpOwogICAgfQp9CgovKiBDb252ZXJ0IGEgY29tcGNvZGUgYml0LWJhc2VkIGVuY29kaW5nIG9mIGEgY29tcGFyaXNvbiBvcGVyYXRvciBiYWNrCiAgIHRvIEdDQydzIGVudW0gdHJlZV9jb2RlIHJlcHJlc2VudGF0aW9uLiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUKICAgaW52ZXJzZSBvZiBjb21wYXJpc29uX3RvX2NvbXBjb2RlLiAgKi8KCnN0YXRpYyBlbnVtIHRyZWVfY29kZQpjb21wY29kZV90b19jb21wYXJpc29uIChpbnQgY29kZSkKewogIHN3aXRjaCAoY29kZSkKICAgIHsKICAgIGNhc2UgQ09NUENPREVfTFQ6CiAgICAgIHJldHVybiBMVF9FWFBSOwogICAgY2FzZSBDT01QQ09ERV9FUToKICAgICAgcmV0dXJuIEVRX0VYUFI7CiAgICBjYXNlIENPTVBDT0RFX0xFOgogICAgICByZXR1cm4gTEVfRVhQUjsKICAgIGNhc2UgQ09NUENPREVfR1Q6CiAgICAgIHJldHVybiBHVF9FWFBSOwogICAgY2FzZSBDT01QQ09ERV9ORToKICAgICAgcmV0dXJuIE5FX0VYUFI7CiAgICBjYXNlIENPTVBDT0RFX0dFOgogICAgICByZXR1cm4gR0VfRVhQUjsKICAgIGRlZmF1bHQ6CiAgICAgIGFib3J0ICgpOwogICAgfQp9CgovKiBSZXR1cm4gbm9uemVybyBpZiBDT0RFIGlzIGEgdHJlZSBjb2RlIHRoYXQgcmVwcmVzZW50cyBhIHRydXRoIHZhbHVlLiAgKi8KCnN0YXRpYyBpbnQKdHJ1dGhfdmFsdWVfcCAoZW51bSB0cmVlX2NvZGUgY29kZSkKewogIHJldHVybiAoVFJFRV9DT0RFX0NMQVNTIChjb2RlKSA9PSAnPCcKCSAgfHwgY29kZSA9PSBUUlVUSF9BTkRfRVhQUiB8fCBjb2RlID09IFRSVVRIX0FORElGX0VYUFIKCSAgfHwgY29kZSA9PSBUUlVUSF9PUl9FWFBSIHx8IGNvZGUgPT0gVFJVVEhfT1JJRl9FWFBSCgkgIHx8IGNvZGUgPT0gVFJVVEhfWE9SX0VYUFIgfHwgY29kZSA9PSBUUlVUSF9OT1RfRVhQUik7Cn0KDAovKiBSZXR1cm4gbm9uemVybyBpZiB0d28gb3BlcmFuZHMgKHR5cGljYWxseSBvZiB0aGUgc2FtZSB0cmVlIG5vZGUpCiAgIGFyZSBuZWNlc3NhcmlseSBlcXVhbC4gIElmIGVpdGhlciBhcmd1bWVudCBoYXMgc2lkZS1lZmZlY3RzIHRoaXMKICAgZnVuY3Rpb24gcmV0dXJucyB6ZXJvLgoKICAgSWYgT05MWV9DT05TVCBpcyBub256ZXJvLCBvbmx5IHJldHVybiBub256ZXJvIGZvciBjb25zdGFudHMuCiAgIFRoaXMgZnVuY3Rpb24gdGVzdHMgd2hldGhlciB0aGUgb3BlcmFuZHMgYXJlIGluZGlzdGluZ3Vpc2hhYmxlOwogICBpdCBkb2VzIG5vdCB0ZXN0IHdoZXRoZXIgdGhleSBhcmUgZXF1YWwgdXNpbmcgQydzID09IG9wZXJhdGlvbi4KICAgVGhlIGRpc3RpbmN0aW9uIGlzIGltcG9ydGFudCBmb3IgSUVFRSBmbG9hdGluZyBwb2ludCwgYmVjYXVzZQogICAoMSkgLTAuMCBhbmQgMC4wIGFyZSBkaXN0aW5ndWlzaGFibGUsIGJ1dCAtMC4wPT0wLjAsIGFuZAogICAoMikgdHdvIE5hTnMgbWF5IGJlIGluZGlzdGluZ3Vpc2hhYmxlLCBidXQgTmFOIT1OYU4uCgogICBJZiBPTkxZX0NPTlNUIGlzIHplcm8sIGEgVkFSX0RFQ0wgaXMgY29uc2lkZXJlZCBlcXVhbCB0byBpdHNlbGYKICAgZXZlbiB0aG91Z2ggaXQgbWF5IGhvbGQgbXVsdGlwbGUgdmFsdWVzIGR1cmluZyBhIGZ1bmN0aW9uLgogICBUaGlzIGlzIGJlY2F1c2UgYSBHQ0MgdHJlZSBub2RlIGd1YXJhbnRlZXMgdGhhdCBub3RoaW5nIGVsc2UgaXMKICAgZXhlY3V0ZWQgYmV0d2VlbiB0aGUgZXZhbHVhdGlvbiBvZiBpdHMgIm9wZXJhbmRzIiAod2hpY2ggbWF5IG9mdGVuCiAgIGJlIGV2YWx1YXRlZCBpbiBhcmJpdHJhcnkgb3JkZXIpLiAgSGVuY2UgaWYgdGhlIG9wZXJhbmRzIHRoZW1zZWx2ZXMKICAgZG9uJ3Qgc2lkZS1lZmZlY3QsIHRoZSBWQVJfREVDTHMsIFBBUk1fREVDTHMgZXRjLi4uIG11c3QgaG9sZCB0aGUKICAgc2FtZSB2YWx1ZSBpbiBlYWNoIG9wZXJhbmQvc3ViZXhwcmVzc2lvbi4gIEhlbmNlIGEgemVybyB2YWx1ZSBmb3IKICAgT05MWV9DT05TVCBhc3N1bWVzIGlzb2Nocm9uaWMgKG9yIGluc3RhbnRhbmVvdXMpIHRyZWUgZXF1aXZhbGVuY2UuCiAgIElmIGNvbXBhcmluZyBhcmJpdHJhcnkgZXhwcmVzc2lvbiB0cmVlcywgc3VjaCBhcyBmcm9tIGRpZmZlcmVudAogICBzdGF0ZW1lbnRzLCBPTkxZX0NPTlNUIG11c3QgdXN1YWxseSBiZSBub256ZXJvLiAgKi8KCmludApvcGVyYW5kX2VxdWFsX3AgKHRyZWUgYXJnMCwgdHJlZSBhcmcxLCBpbnQgb25seV9jb25zdCkKewogIHRyZWUgZm5kZWNsOwoKICAvKiBJZiBib3RoIHR5cGVzIGRvbid0IGhhdmUgdGhlIHNhbWUgc2lnbmVkbmVzcywgdGhlbiB3ZSBjYW4ndCBjb25zaWRlcgogICAgIHRoZW0gZXF1YWwuICBXZSBtdXN0IGNoZWNrIHRoaXMgYmVmb3JlIHRoZSBTVFJJUF9OT1BTIGNhbGxzCiAgICAgYmVjYXVzZSB0aGV5IG1heSBjaGFuZ2UgdGhlIHNpZ25lZG5lc3Mgb2YgdGhlIGFyZ3VtZW50cy4gICovCiAgaWYgKFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAoYXJnMCkpICE9IFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAoYXJnMSkpKQogICAgcmV0dXJuIDA7CgogIFNUUklQX05PUFMgKGFyZzApOwogIFNUUklQX05PUFMgKGFyZzEpOwoKICBpZiAoVFJFRV9DT0RFIChhcmcwKSAhPSBUUkVFX0NPREUgKGFyZzEpCiAgICAgIC8qIFRoaXMgaXMgbmVlZGVkIGZvciBjb252ZXJzaW9ucyBhbmQgZm9yIENPTVBPTkVOVF9SRUYuCgkgTWlnaHQgYXMgd2VsbCBwbGF5IGl0IHNhZmUgYW5kIGFsd2F5cyB0ZXN0IHRoaXMuICAqLwogICAgICB8fCBUUkVFX0NPREUgKFRSRUVfVFlQRSAoYXJnMCkpID09IEVSUk9SX01BUksKICAgICAgfHwgVFJFRV9DT0RFIChUUkVFX1RZUEUgKGFyZzEpKSA9PSBFUlJPUl9NQVJLCiAgICAgIHx8IFRZUEVfTU9ERSAoVFJFRV9UWVBFIChhcmcwKSkgIT0gVFlQRV9NT0RFIChUUkVFX1RZUEUgKGFyZzEpKSkKICAgIHJldHVybiAwOwoKICAvKiBJZiBBUkcwIGFuZCBBUkcxIGFyZSB0aGUgc2FtZSBTQVZFX0VYUFIsIHRoZXkgYXJlIG5lY2Vzc2FyaWx5IGVxdWFsLgogICAgIFdlIGRvbid0IGNhcmUgYWJvdXQgc2lkZSBlZmZlY3RzIGluIHRoYXQgY2FzZSBiZWNhdXNlIHRoZSBTQVZFX0VYUFIKICAgICB0YWtlcyBjYXJlIG9mIHRoYXQgZm9yIHVzLiBJbiBhbGwgb3RoZXIgY2FzZXMsIHR3byBleHByZXNzaW9ucyBhcmUKICAgICBlcXVhbCBpZiB0aGV5IGhhdmUgbm8gc2lkZSBlZmZlY3RzLiAgSWYgd2UgaGF2ZSB0d28gaWRlbnRpY2FsCiAgICAgZXhwcmVzc2lvbnMgd2l0aCBzaWRlIGVmZmVjdHMgdGhhdCBzaG91bGQgYmUgdHJlYXRlZCB0aGUgc2FtZSBkdWUKICAgICB0byB0aGUgb25seSBzaWRlIGVmZmVjdHMgYmVpbmcgaWRlbnRpY2FsIFNBVkVfRVhQUidzLCB0aGF0IHdpbGwKICAgICBiZSBkZXRlY3RlZCBpbiB0aGUgcmVjdXJzaXZlIGNhbGxzIGJlbG93LiAgKi8KICBpZiAoYXJnMCA9PSBhcmcxICYmICEgb25seV9jb25zdAogICAgICAmJiAoVFJFRV9DT0RFIChhcmcwKSA9PSBTQVZFX0VYUFIKCSAgfHwgKCEgVFJFRV9TSURFX0VGRkVDVFMgKGFyZzApICYmICEgVFJFRV9TSURFX0VGRkVDVFMgKGFyZzEpKSkpCiAgICByZXR1cm4gMTsKCiAgLyogTmV4dCBoYW5kbGUgY29uc3RhbnQgY2FzZXMsIHRob3NlIGZvciB3aGljaCB3ZSBjYW4gcmV0dXJuIDEgZXZlbgogICAgIGlmIE9OTFlfQ09OU1QgaXMgc2V0LiAgKi8KICBpZiAoVFJFRV9DT05TVEFOVCAoYXJnMCkgJiYgVFJFRV9DT05TVEFOVCAoYXJnMSkpCiAgICBzd2l0Y2ggKFRSRUVfQ09ERSAoYXJnMCkpCiAgICAgIHsKICAgICAgY2FzZSBJTlRFR0VSX0NTVDoKCXJldHVybiAoISBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcwKQoJCSYmICEgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAoYXJnMSkKCQkmJiB0cmVlX2ludF9jc3RfZXF1YWwgKGFyZzAsIGFyZzEpKTsKCiAgICAgIGNhc2UgUkVBTF9DU1Q6CglyZXR1cm4gKCEgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAoYXJnMCkKCQkmJiAhIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKGFyZzEpCgkJJiYgUkVBTF9WQUxVRVNfSURFTlRJQ0FMIChUUkVFX1JFQUxfQ1NUIChhcmcwKSwKCQkJCQkgIFRSRUVfUkVBTF9DU1QgKGFyZzEpKSk7CgogICAgICBjYXNlIFZFQ1RPUl9DU1Q6Cgl7CgkgIHRyZWUgdjEsIHYyOwoKCSAgaWYgKFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKGFyZzApCgkgICAgICB8fCBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcxKSkKCSAgICByZXR1cm4gMDsKCgkgIHYxID0gVFJFRV9WRUNUT1JfQ1NUX0VMVFMgKGFyZzApOwoJICB2MiA9IFRSRUVfVkVDVE9SX0NTVF9FTFRTIChhcmcxKTsKCSAgd2hpbGUgKHYxICYmIHYyKQoJICAgIHsKCSAgICAgIGlmICghb3BlcmFuZF9lcXVhbF9wICh2MSwgdjIsIG9ubHlfY29uc3QpKQoJCXJldHVybiAwOwoJICAgICAgdjEgPSBUUkVFX0NIQUlOICh2MSk7CgkgICAgICB2MiA9IFRSRUVfQ0hBSU4gKHYyKTsKCSAgICB9CgoJICByZXR1cm4gMTsKCX0KCiAgICAgIGNhc2UgQ09NUExFWF9DU1Q6CglyZXR1cm4gKG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9SRUFMUEFSVCAoYXJnMCksIFRSRUVfUkVBTFBBUlQgKGFyZzEpLAoJCQkJIG9ubHlfY29uc3QpCgkJJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX0lNQUdQQVJUIChhcmcwKSwgVFJFRV9JTUFHUEFSVCAoYXJnMSksCgkJCQkgICAgb25seV9jb25zdCkpOwoKICAgICAgY2FzZSBTVFJJTkdfQ1NUOgoJcmV0dXJuIChUUkVFX1NUUklOR19MRU5HVEggKGFyZzApID09IFRSRUVfU1RSSU5HX0xFTkdUSCAoYXJnMSkKCQkmJiAhIG1lbWNtcCAoVFJFRV9TVFJJTkdfUE9JTlRFUiAoYXJnMCksCgkJCSAgICAgIFRSRUVfU1RSSU5HX1BPSU5URVIgKGFyZzEpLAoJCQkgICAgICBUUkVFX1NUUklOR19MRU5HVEggKGFyZzApKSk7CgogICAgICBjYXNlIEFERFJfRVhQUjoKCXJldHVybiBvcGVyYW5kX2VxdWFsX3AgKFRSRUVfT1BFUkFORCAoYXJnMCwgMCksIFRSRUVfT1BFUkFORCAoYXJnMSwgMCksCgkJCQkwKTsKICAgICAgZGVmYXVsdDoKCWJyZWFrOwogICAgICB9CgogIGlmIChvbmx5X2NvbnN0KQogICAgcmV0dXJuIDA7CgogIHN3aXRjaCAoVFJFRV9DT0RFX0NMQVNTIChUUkVFX0NPREUgKGFyZzApKSkKICAgIHsKICAgIGNhc2UgJzEnOgogICAgICAvKiBUd28gY29udmVyc2lvbnMgYXJlIGVxdWFsIG9ubHkgaWYgc2lnbmVkbmVzcyBhbmQgbW9kZXMgbWF0Y2guICAqLwogICAgICBzd2l0Y2ggKFRSRUVfQ09ERSAoYXJnMCkpCiAgICAgICAgewogICAgICAgIGNhc2UgTk9QX0VYUFI6CiAgICAgICAgY2FzZSBDT05WRVJUX0VYUFI6CiAgICAgICAgY2FzZSBGSVhfQ0VJTF9FWFBSOgogICAgICAgIGNhc2UgRklYX1RSVU5DX0VYUFI6CiAgICAgICAgY2FzZSBGSVhfRkxPT1JfRVhQUjoKICAgICAgICBjYXNlIEZJWF9ST1VORF9FWFBSOgoJICBpZiAoVFJFRV9VTlNJR05FRCAoVFJFRV9UWVBFIChhcmcwKSkKCSAgICAgICE9IFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAoYXJnMSkpKQoJICAgIHJldHVybiAwOwoJICBicmVhazsKCWRlZmF1bHQ6CgkgIGJyZWFrOwoJfQoKICAgICAgcmV0dXJuIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwKCQkJICAgICAgVFJFRV9PUEVSQU5EIChhcmcxLCAwKSwgMCk7CgogICAgY2FzZSAnPCc6CiAgICBjYXNlICcyJzoKICAgICAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgVFJFRV9PUEVSQU5EIChhcmcxLCAwKSwgMCkKCSAgJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpLCBUUkVFX09QRVJBTkQgKGFyZzEsIDEpLAoJCQkgICAgICAwKSkKCXJldHVybiAxOwoKICAgICAgLyogRm9yIGNvbW11dGF0aXZlIG9wcywgYWxsb3cgdGhlIG90aGVyIG9yZGVyLiAgKi8KICAgICAgcmV0dXJuICgoVFJFRV9DT0RFIChhcmcwKSA9PSBQTFVTX0VYUFIgfHwgVFJFRV9DT0RFIChhcmcwKSA9PSBNVUxUX0VYUFIKCSAgICAgICB8fCBUUkVFX0NPREUgKGFyZzApID09IE1JTl9FWFBSIHx8IFRSRUVfQ09ERSAoYXJnMCkgPT0gTUFYX0VYUFIKCSAgICAgICB8fCBUUkVFX0NPREUgKGFyZzApID09IEJJVF9JT1JfRVhQUgoJICAgICAgIHx8IFRSRUVfQ09ERSAoYXJnMCkgPT0gQklUX1hPUl9FWFBSCgkgICAgICAgfHwgVFJFRV9DT0RFIChhcmcwKSA9PSBCSVRfQU5EX0VYUFIKCSAgICAgICB8fCBUUkVFX0NPREUgKGFyZzApID09IE5FX0VYUFIgfHwgVFJFRV9DT0RFIChhcmcwKSA9PSBFUV9FWFBSKQoJICAgICAgJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkJICBUUkVFX09QRVJBTkQgKGFyZzEsIDEpLCAwKQoJICAgICAgJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpLAoJCQkJICBUUkVFX09QRVJBTkQgKGFyZzEsIDApLCAwKSk7CgogICAgY2FzZSAncic6CiAgICAgIC8qIElmIGVpdGhlciBvZiB0aGUgcG9pbnRlciAob3IgcmVmZXJlbmNlKSBleHByZXNzaW9ucyB3ZSBhcmUKCSBkZXJlZmVyZW5jaW5nIGNvbnRhaW4gYSBzaWRlIGVmZmVjdCwgdGhlc2UgY2Fubm90IGJlIGVxdWFsLiAgKi8KICAgICAgaWYgKFRSRUVfU0lERV9FRkZFQ1RTIChhcmcwKQoJICB8fCBUUkVFX1NJREVfRUZGRUNUUyAoYXJnMSkpCglyZXR1cm4gMDsKCiAgICAgIHN3aXRjaCAoVFJFRV9DT0RFIChhcmcwKSkKCXsKCWNhc2UgSU5ESVJFQ1RfUkVGOgoJICByZXR1cm4gb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkJICBUUkVFX09QRVJBTkQgKGFyZzEsIDApLCAwKTsKCgljYXNlIENPTVBPTkVOVF9SRUY6CgljYXNlIEFSUkFZX1JFRjoKCWNhc2UgQVJSQVlfUkFOR0VfUkVGOgoJICByZXR1cm4gKG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwKCQkJCSAgIFRSRUVfT1BFUkFORCAoYXJnMSwgMCksIDApCgkJICAmJiBvcGVyYW5kX2VxdWFsX3AgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSksCgkJCQkgICAgICBUUkVFX09QRVJBTkQgKGFyZzEsIDEpLCAwKSk7CgoJY2FzZSBCSVRfRklFTERfUkVGOgoJICByZXR1cm4gKG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwKCQkJCSAgIFRSRUVfT1BFUkFORCAoYXJnMSwgMCksIDApCgkJICAmJiBvcGVyYW5kX2VxdWFsX3AgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSksCgkJCQkgICAgICBUUkVFX09QRVJBTkQgKGFyZzEsIDEpLCAwKQoJCSAgJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDIpLAoJCQkJICAgICAgVFJFRV9PUEVSQU5EIChhcmcxLCAyKSwgMCkpOwoJZGVmYXVsdDoKCSAgcmV0dXJuIDA7Cgl9CgogICAgY2FzZSAnZSc6CiAgICAgIHN3aXRjaCAoVFJFRV9DT0RFIChhcmcwKSkKCXsKCWNhc2UgQUREUl9FWFBSOgoJY2FzZSBUUlVUSF9OT1RfRVhQUjoKCSAgcmV0dXJuIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwKCQkJCSAgVFJFRV9PUEVSQU5EIChhcmcxLCAwKSwgMCk7CgoJY2FzZSBSVExfRVhQUjoKCSAgcmV0dXJuIHJ0eF9lcXVhbF9wIChSVExfRVhQUl9SVEwgKGFyZzApLCBSVExfRVhQUl9SVEwgKGFyZzEpKTsKCgljYXNlIENBTExfRVhQUjoKCSAgLyogSWYgdGhlIENBTExfRVhQUnMgY2FsbCBkaWZmZXJlbnQgZnVuY3Rpb25zLCB0aGVuIHRoZXkKCSAgICAgY2xlYXJseSBjYW4gbm90IGJlIGVxdWFsLiAgKi8KCSAgaWYgKCEgb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkJIFRSRUVfT1BFUkFORCAoYXJnMSwgMCksIDApKQoJICAgIHJldHVybiAwOwoKCSAgLyogT25seSBjb25zaWRlciBjb25zdCBmdW5jdGlvbnMgZXF1aXZhbGVudC4gICovCgkgIGZuZGVjbCA9IGdldF9jYWxsZWVfZm5kZWNsIChhcmcwKTsKCSAgaWYgKGZuZGVjbCA9PSBOVUxMX1RSRUUKCSAgICAgIHx8ICEgKGZsYWdzX2Zyb21fZGVjbF9vcl90eXBlIChmbmRlY2wpICYgRUNGX0NPTlNUKSkKCSAgICByZXR1cm4gMDsKCgkgIC8qIE5vdyBzZWUgaWYgYWxsIHRoZSBhcmd1bWVudHMgYXJlIHRoZSBzYW1lLiAgb3BlcmFuZF9lcXVhbF9wCgkgICAgIGRvZXMgbm90IGhhbmRsZSBUUkVFX0xJU1QsIHNvIHdlIHdhbGsgdGhlIG9wZXJhbmRzIGhlcmUKCSAgICAgZmVlZGluZyB0aGVtIHRvIG9wZXJhbmRfZXF1YWxfcC4gICovCgkgIGFyZzAgPSBUUkVFX09QRVJBTkQgKGFyZzAsIDEpOwoJICBhcmcxID0gVFJFRV9PUEVSQU5EIChhcmcxLCAxKTsKCSAgd2hpbGUgKGFyZzAgJiYgYXJnMSkKCSAgICB7CgkgICAgICBpZiAoISBvcGVyYW5kX2VxdWFsX3AgKFRSRUVfVkFMVUUgKGFyZzApLCBUUkVFX1ZBTFVFIChhcmcxKSwgMCkpCgkJcmV0dXJuIDA7CgoJICAgICAgYXJnMCA9IFRSRUVfQ0hBSU4gKGFyZzApOwoJICAgICAgYXJnMSA9IFRSRUVfQ0hBSU4gKGFyZzEpOwoJICAgIH0KCgkgIC8qIElmIHdlIGdldCBoZXJlIGFuZCBib3RoIGFyZ3VtZW50IGxpc3RzIGFyZSBleGhhdXN0ZWQKCSAgICAgdGhlbiB0aGUgQ0FMTF9FWFBScyBhcmUgZXF1YWwuICAqLwoJICByZXR1cm4gISAoYXJnMCB8fCBhcmcxKTsKCglkZWZhdWx0OgoJICByZXR1cm4gMDsKCX0KCiAgICBjYXNlICdkJzoKCS8qIENvbnNpZGVyIF9fYnVpbHRpbl9zcXJ0IGVxdWFsIHRvIHNxcnQuICAqLwoJcmV0dXJuIFRSRUVfQ09ERSAoYXJnMCkgPT0gRlVOQ1RJT05fREVDTAoJICAgICAgICYmIERFQ0xfQlVJTFRfSU4gKGFyZzApICYmIERFQ0xfQlVJTFRfSU4gKGFyZzEpCgkgICAgICAgJiYgREVDTF9CVUlMVF9JTl9DTEFTUyAoYXJnMCkgPT0gREVDTF9CVUlMVF9JTl9DTEFTUyAoYXJnMSkKCSAgICAgICAmJiBERUNMX0ZVTkNUSU9OX0NPREUgKGFyZzApID09IERFQ0xfRlVOQ1RJT05fQ09ERSAoYXJnMSk7CgogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KDAovKiBTaW1pbGFyIHRvIG9wZXJhbmRfZXF1YWxfcCwgYnV0IHNlZSBpZiBBUkcwIG1pZ2h0IGhhdmUgYmVlbiBtYWRlIGJ5CiAgIHNob3J0ZW5fY29tcGFyZSBmcm9tIEFSRzEgd2hlbiBBUkcxIHdhcyBiZWluZyBjb21wYXJlZCB3aXRoIE9USEVSLgoKICAgV2hlbiBpbiBkb3VidCwgcmV0dXJuIDAuICAqLwoKc3RhdGljIGludApvcGVyYW5kX2VxdWFsX2Zvcl9jb21wYXJpc29uX3AgKHRyZWUgYXJnMCwgdHJlZSBhcmcxLCB0cmVlIG90aGVyKQp7CiAgaW50IHVuc2lnbmVkcDEsIHVuc2lnbmVkcG87CiAgdHJlZSBwcmltYXJnMCwgcHJpbWFyZzEsIHByaW1vdGhlcjsKICB1bnNpZ25lZCBpbnQgY29ycmVjdF93aWR0aDsKCiAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoYXJnMCwgYXJnMSwgMCkpCiAgICByZXR1cm4gMTsKCiAgaWYgKCEgSU5URUdSQUxfVFlQRV9QIChUUkVFX1RZUEUgKGFyZzApKQogICAgICB8fCAhIElOVEVHUkFMX1RZUEVfUCAoVFJFRV9UWVBFIChhcmcxKSkpCiAgICByZXR1cm4gMDsKCiAgLyogRGlzY2FyZCBhbnkgY29udmVyc2lvbnMgdGhhdCBkb24ndCBjaGFuZ2UgdGhlIG1vZGVzIG9mIEFSRzAgYW5kIEFSRzEKICAgICBhbmQgc2VlIGlmIHRoZSBpbm5lciB2YWx1ZXMgYXJlIHRoZSBzYW1lLiAgVGhpcyByZW1vdmVzIGFueQogICAgIHNpZ25lZG5lc3MgY29tcGFyaXNvbiwgd2hpY2ggZG9lc24ndCBtYXR0ZXIgaGVyZS4gICovCiAgcHJpbWFyZzAgPSBhcmcwLCBwcmltYXJnMSA9IGFyZzE7CiAgU1RSSVBfTk9QUyAocHJpbWFyZzApOwogIFNUUklQX05PUFMgKHByaW1hcmcxKTsKICBpZiAob3BlcmFuZF9lcXVhbF9wIChwcmltYXJnMCwgcHJpbWFyZzEsIDApKQogICAgcmV0dXJuIDE7CgogIC8qIER1cGxpY2F0ZSB3aGF0IHNob3J0ZW5fY29tcGFyZSBkb2VzIHRvIEFSRzEgYW5kIHNlZSBpZiB0aGF0IGdpdmVzIHRoZQogICAgIGFjdHVhbCBjb21wYXJpc29uIG9wZXJhbmQsIEFSRzAuCgogICAgIEZpcnN0IHRocm93IGF3YXkgYW55IGNvbnZlcnNpb25zIHRvIHdpZGVyIHR5cGVzCiAgICAgYWxyZWFkeSBwcmVzZW50IGluIHRoZSBvcGVyYW5kcy4gICovCgogIHByaW1hcmcxID0gZ2V0X25hcnJvd2VyIChhcmcxLCAmdW5zaWduZWRwMSk7CiAgcHJpbW90aGVyID0gZ2V0X25hcnJvd2VyIChvdGhlciwgJnVuc2lnbmVkcG8pOwoKICBjb3JyZWN0X3dpZHRoID0gVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAoYXJnMSkpOwogIGlmICh1bnNpZ25lZHAxID09IHVuc2lnbmVkcG8KICAgICAgJiYgVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAocHJpbWFyZzEpKSA8IGNvcnJlY3Rfd2lkdGgKICAgICAgJiYgVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAocHJpbW90aGVyKSkgPCBjb3JyZWN0X3dpZHRoKQogICAgewogICAgICB0cmVlIHR5cGUgPSBUUkVFX1RZUEUgKGFyZzApOwoKICAgICAgLyogTWFrZSBzdXJlIHNob3J0ZXIgb3BlcmFuZCBpcyBleHRlbmRlZCB0aGUgcmlnaHQgd2F5CgkgdG8gbWF0Y2ggdGhlIGxvbmdlciBvcGVyYW5kLiAgKi8KICAgICAgcHJpbWFyZzEgPSBmb2xkX2NvbnZlcnQgKCgqbGFuZ19ob29rcy50eXBlcy5zaWduZWRfb3JfdW5zaWduZWRfdHlwZSkKCQkJICAgICAgICh1bnNpZ25lZHAxLCBUUkVFX1RZUEUgKHByaW1hcmcxKSksIHByaW1hcmcxKTsKCiAgICAgIGlmIChvcGVyYW5kX2VxdWFsX3AgKGFyZzAsIGZvbGRfY29udmVydCAodHlwZSwgcHJpbWFyZzEpLCAwKSkKCXJldHVybiAxOwogICAgfQoKICByZXR1cm4gMDsKfQoMCi8qIFNlZSBpZiBBUkcgaXMgYW4gZXhwcmVzc2lvbiB0aGF0IGlzIGVpdGhlciBhIGNvbXBhcmlzb24gb3IgaXMgcGVyZm9ybWluZwogICBhcml0aG1ldGljIG9uIGNvbXBhcmlzb25zLiAgVGhlIGNvbXBhcmlzb25zIG11c3Qgb25seSBiZSBjb21wYXJpbmcKICAgdHdvIGRpZmZlcmVudCB2YWx1ZXMsIHdoaWNoIHdpbGwgYmUgc3RvcmVkIGluICpDVkFMMSBhbmQgKkNWQUwyOyBpZgogICB0aGV5IGFyZSBub256ZXJvIGl0IG1lYW5zIHRoYXQgc29tZSBvcGVyYW5kcyBoYXZlIGFscmVhZHkgYmVlbiBmb3VuZC4KICAgTm8gdmFyaWFibGVzIG1heSBiZSB1c2VkIGFueXdoZXJlIGVsc2UgaW4gdGhlIGV4cHJlc3Npb24gZXhjZXB0IGluIHRoZQogICBjb21wYXJpc29ucy4gIElmIFNBVkVfUCBpcyB0cnVlIGl0IG1lYW5zIHdlIHJlbW92ZWQgYSBTQVZFX0VYUFIgYXJvdW5kCiAgIHRoZSBleHByZXNzaW9uIGFuZCBzYXZlX2V4cHIgbmVlZHMgdG8gYmUgY2FsbGVkIHdpdGggQ1ZBTDEgYW5kIENWQUwyLgoKICAgSWYgdGhpcyBpcyB0cnVlLCByZXR1cm4gMS4gIE90aGVyd2lzZSwgcmV0dXJuIHplcm8uICAqLwoKc3RhdGljIGludAp0d292YWxfY29tcGFyaXNvbl9wICh0cmVlIGFyZywgdHJlZSAqY3ZhbDEsIHRyZWUgKmN2YWwyLCBpbnQgKnNhdmVfcCkKewogIGVudW0gdHJlZV9jb2RlIGNvZGUgPSBUUkVFX0NPREUgKGFyZyk7CiAgY2hhciBjbGFzcyA9IFRSRUVfQ09ERV9DTEFTUyAoY29kZSk7CgogIC8qIFdlIGNhbiBoYW5kbGUgc29tZSBvZiB0aGUgJ2UnIGNhc2VzIGhlcmUuICAqLwogIGlmIChjbGFzcyA9PSAnZScgJiYgY29kZSA9PSBUUlVUSF9OT1RfRVhQUikKICAgIGNsYXNzID0gJzEnOwogIGVsc2UgaWYgKGNsYXNzID09ICdlJwoJICAgJiYgKGNvZGUgPT0gVFJVVEhfQU5ESUZfRVhQUiB8fCBjb2RlID09IFRSVVRIX09SSUZfRVhQUgoJICAgICAgIHx8IGNvZGUgPT0gQ09NUE9VTkRfRVhQUikpCiAgICBjbGFzcyA9ICcyJzsKCiAgZWxzZSBpZiAoY2xhc3MgPT0gJ2UnICYmIGNvZGUgPT0gU0FWRV9FWFBSICYmIFNBVkVfRVhQUl9SVEwgKGFyZykgPT0gMAoJICAgJiYgISBUUkVFX1NJREVfRUZGRUNUUyAoVFJFRV9PUEVSQU5EIChhcmcsIDApKSkKICAgIHsKICAgICAgLyogSWYgd2UndmUgYWxyZWFkeSBmb3VuZCBhIENWQUwxIG9yIENWQUwyLCB0aGlzIGV4cHJlc3Npb24gaXMKCSB0d28gY29tcGxleCB0byBoYW5kbGUuICAqLwogICAgICBpZiAoKmN2YWwxIHx8ICpjdmFsMikKCXJldHVybiAwOwoKICAgICAgY2xhc3MgPSAnMSc7CiAgICAgICpzYXZlX3AgPSAxOwogICAgfQoKICBzd2l0Y2ggKGNsYXNzKQogICAgewogICAgY2FzZSAnMSc6CiAgICAgIHJldHVybiB0d292YWxfY29tcGFyaXNvbl9wIChUUkVFX09QRVJBTkQgKGFyZywgMCksIGN2YWwxLCBjdmFsMiwgc2F2ZV9wKTsKCiAgICBjYXNlICcyJzoKICAgICAgcmV0dXJuICh0d292YWxfY29tcGFyaXNvbl9wIChUUkVFX09QRVJBTkQgKGFyZywgMCksIGN2YWwxLCBjdmFsMiwgc2F2ZV9wKQoJICAgICAgJiYgdHdvdmFsX2NvbXBhcmlzb25fcCAoVFJFRV9PUEVSQU5EIChhcmcsIDEpLAoJCQkJICAgICAgY3ZhbDEsIGN2YWwyLCBzYXZlX3ApKTsKCiAgICBjYXNlICdjJzoKICAgICAgcmV0dXJuIDE7CgogICAgY2FzZSAnZSc6CiAgICAgIGlmIChjb2RlID09IENPTkRfRVhQUikKCXJldHVybiAodHdvdmFsX2NvbXBhcmlzb25fcCAoVFJFRV9PUEVSQU5EIChhcmcsIDApLAoJCQkJICAgICBjdmFsMSwgY3ZhbDIsIHNhdmVfcCkKCQkmJiB0d292YWxfY29tcGFyaXNvbl9wIChUUkVFX09QRVJBTkQgKGFyZywgMSksCgkJCQkJY3ZhbDEsIGN2YWwyLCBzYXZlX3ApCgkJJiYgdHdvdmFsX2NvbXBhcmlzb25fcCAoVFJFRV9PUEVSQU5EIChhcmcsIDIpLAoJCQkJCWN2YWwxLCBjdmFsMiwgc2F2ZV9wKSk7CiAgICAgIHJldHVybiAwOwoKICAgIGNhc2UgJzwnOgogICAgICAvKiBGaXJzdCBzZWUgaWYgd2UgY2FuIGhhbmRsZSB0aGUgZmlyc3Qgb3BlcmFuZCwgdGhlbiB0aGUgc2Vjb25kLiAgRm9yCgkgdGhlIHNlY29uZCBvcGVyYW5kLCB3ZSBrbm93ICpDVkFMMSBjYW4ndCBiZSB6ZXJvLiAgSXQgbXVzdCBiZSB0aGF0Cgkgb25lIHNpZGUgb2YgdGhlIGNvbXBhcmlzb24gaXMgZWFjaCBvZiB0aGUgdmFsdWVzOyB0ZXN0IGZvciB0aGUKCSBjYXNlIHdoZXJlIHRoaXMgaXNuJ3QgdHJ1ZSBieSBmYWlsaW5nIGlmIHRoZSB0d28gb3BlcmFuZHMKCSBhcmUgdGhlIHNhbWUuICAqLwoKICAgICAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcsIDApLAoJCQkgICBUUkVFX09QRVJBTkQgKGFyZywgMSksIDApKQoJcmV0dXJuIDA7CgogICAgICBpZiAoKmN2YWwxID09IDApCgkqY3ZhbDEgPSBUUkVFX09QRVJBTkQgKGFyZywgMCk7CiAgICAgIGVsc2UgaWYgKG9wZXJhbmRfZXF1YWxfcCAoKmN2YWwxLCBUUkVFX09QRVJBTkQgKGFyZywgMCksIDApKQoJOwogICAgICBlbHNlIGlmICgqY3ZhbDIgPT0gMCkKCSpjdmFsMiA9IFRSRUVfT1BFUkFORCAoYXJnLCAwKTsKICAgICAgZWxzZSBpZiAob3BlcmFuZF9lcXVhbF9wICgqY3ZhbDIsIFRSRUVfT1BFUkFORCAoYXJnLCAwKSwgMCkpCgk7CiAgICAgIGVsc2UKCXJldHVybiAwOwoKICAgICAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoKmN2YWwxLCBUUkVFX09QRVJBTkQgKGFyZywgMSksIDApKQoJOwogICAgICBlbHNlIGlmICgqY3ZhbDIgPT0gMCkKCSpjdmFsMiA9IFRSRUVfT1BFUkFORCAoYXJnLCAxKTsKICAgICAgZWxzZSBpZiAob3BlcmFuZF9lcXVhbF9wICgqY3ZhbDIsIFRSRUVfT1BFUkFORCAoYXJnLCAxKSwgMCkpCgk7CiAgICAgIGVsc2UKCXJldHVybiAwOwoKICAgICAgcmV0dXJuIDE7CgogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KDAovKiBBUkcgaXMgYSB0cmVlIHRoYXQgaXMga25vd24gdG8gY29udGFpbiBqdXN0IGFyaXRobWV0aWMgb3BlcmF0aW9ucyBhbmQKICAgY29tcGFyaXNvbnMuICBFdmFsdWF0ZSB0aGUgb3BlcmF0aW9ucyBpbiB0aGUgdHJlZSBzdWJzdGl0dXRpbmcgTkVXMCBmb3IKICAgYW55IG9jY3VycmVuY2Ugb2YgT0xEMCBhcyBhbiBvcGVyYW5kIG9mIGEgY29tcGFyaXNvbiBhbmQgbGlrZXdpc2UgZm9yCiAgIE5FVzEgYW5kIE9MRDEuICAqLwoKc3RhdGljIHRyZWUKZXZhbF9zdWJzdCAodHJlZSBhcmcsIHRyZWUgb2xkMCwgdHJlZSBuZXcwLCB0cmVlIG9sZDEsIHRyZWUgbmV3MSkKewogIHRyZWUgdHlwZSA9IFRSRUVfVFlQRSAoYXJnKTsKICBlbnVtIHRyZWVfY29kZSBjb2RlID0gVFJFRV9DT0RFIChhcmcpOwogIGNoYXIgY2xhc3MgPSBUUkVFX0NPREVfQ0xBU1MgKGNvZGUpOwoKICAvKiBXZSBjYW4gaGFuZGxlIHNvbWUgb2YgdGhlICdlJyBjYXNlcyBoZXJlLiAgKi8KICBpZiAoY2xhc3MgPT0gJ2UnICYmIGNvZGUgPT0gVFJVVEhfTk9UX0VYUFIpCiAgICBjbGFzcyA9ICcxJzsKICBlbHNlIGlmIChjbGFzcyA9PSAnZScKCSAgICYmIChjb2RlID09IFRSVVRIX0FORElGX0VYUFIgfHwgY29kZSA9PSBUUlVUSF9PUklGX0VYUFIpKQogICAgY2xhc3MgPSAnMic7CgogIHN3aXRjaCAoY2xhc3MpCiAgICB7CiAgICBjYXNlICcxJzoKICAgICAgcmV0dXJuIGZvbGQgKGJ1aWxkMSAoY29kZSwgdHlwZSwKCQkJICAgZXZhbF9zdWJzdCAoVFJFRV9PUEVSQU5EIChhcmcsIDApLAoJCQkJICAgICAgIG9sZDAsIG5ldzAsIG9sZDEsIG5ldzEpKSk7CgogICAgY2FzZSAnMic6CiAgICAgIHJldHVybiBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwKCQkJICBldmFsX3N1YnN0IChUUkVFX09QRVJBTkQgKGFyZywgMCksCgkJCQkgICAgICBvbGQwLCBuZXcwLCBvbGQxLCBuZXcxKSwKCQkJICBldmFsX3N1YnN0IChUUkVFX09QRVJBTkQgKGFyZywgMSksCgkJCQkgICAgICBvbGQwLCBuZXcwLCBvbGQxLCBuZXcxKSkpOwoKICAgIGNhc2UgJ2UnOgogICAgICBzd2l0Y2ggKGNvZGUpCgl7CgljYXNlIFNBVkVfRVhQUjoKCSAgcmV0dXJuIGV2YWxfc3Vic3QgKFRSRUVfT1BFUkFORCAoYXJnLCAwKSwgb2xkMCwgbmV3MCwgb2xkMSwgbmV3MSk7CgoJY2FzZSBDT01QT1VORF9FWFBSOgoJICByZXR1cm4gZXZhbF9zdWJzdCAoVFJFRV9PUEVSQU5EIChhcmcsIDEpLCBvbGQwLCBuZXcwLCBvbGQxLCBuZXcxKTsKCgljYXNlIENPTkRfRVhQUjoKCSAgcmV0dXJuIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLAoJCQkgICAgICBldmFsX3N1YnN0IChUUkVFX09QRVJBTkQgKGFyZywgMCksCgkJCQkJICBvbGQwLCBuZXcwLCBvbGQxLCBuZXcxKSwKCQkJICAgICAgZXZhbF9zdWJzdCAoVFJFRV9PUEVSQU5EIChhcmcsIDEpLAoJCQkJCSAgb2xkMCwgbmV3MCwgb2xkMSwgbmV3MSksCgkJCSAgICAgIGV2YWxfc3Vic3QgKFRSRUVfT1BFUkFORCAoYXJnLCAyKSwKCQkJCQkgIG9sZDAsIG5ldzAsIG9sZDEsIG5ldzEpKSk7CglkZWZhdWx0OgoJICBicmVhazsKCX0KICAgICAgLyogRmFsbCB0aHJvdWdoIC0gPz8/ICAqLwoKICAgIGNhc2UgJzwnOgogICAgICB7Cgl0cmVlIGFyZzAgPSBUUkVFX09QRVJBTkQgKGFyZywgMCk7Cgl0cmVlIGFyZzEgPSBUUkVFX09QRVJBTkQgKGFyZywgMSk7CgoJLyogV2UgbmVlZCB0byBjaGVjayBib3RoIGZvciBleGFjdCBlcXVhbGl0eSBhbmQgdHJlZSBlcXVhbGl0eS4gIFRoZQoJICAgZm9ybWVyIHdpbGwgYmUgdHJ1ZSBpZiB0aGUgb3BlcmFuZCBoYXMgYSBzaWRlLWVmZmVjdC4gIEluIHRoYXQKCSAgIGNhc2UsIHdlIGtub3cgdGhlIG9wZXJhbmQgb2NjdXJyZWQgZXhhY3RseSBvbmNlLiAgKi8KCglpZiAoYXJnMCA9PSBvbGQwIHx8IG9wZXJhbmRfZXF1YWxfcCAoYXJnMCwgb2xkMCwgMCkpCgkgIGFyZzAgPSBuZXcwOwoJZWxzZSBpZiAoYXJnMCA9PSBvbGQxIHx8IG9wZXJhbmRfZXF1YWxfcCAoYXJnMCwgb2xkMSwgMCkpCgkgIGFyZzAgPSBuZXcxOwoKCWlmIChhcmcxID09IG9sZDAgfHwgb3BlcmFuZF9lcXVhbF9wIChhcmcxLCBvbGQwLCAwKSkKCSAgYXJnMSA9IG5ldzA7CgllbHNlIGlmIChhcmcxID09IG9sZDEgfHwgb3BlcmFuZF9lcXVhbF9wIChhcmcxLCBvbGQxLCAwKSkKCSAgYXJnMSA9IG5ldzE7CgoJcmV0dXJuIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLCBhcmcwLCBhcmcxKSk7CiAgICAgIH0KCiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gYXJnOwogICAgfQp9CgwKLyogUmV0dXJuIGEgdHJlZSBmb3IgdGhlIGNhc2Ugd2hlbiB0aGUgcmVzdWx0IG9mIGFuIGV4cHJlc3Npb24gaXMgUkVTVUxUCiAgIGNvbnZlcnRlZCB0byBUWVBFIGFuZCBPTUlUVEVEIHdhcyBwcmV2aW91c2x5IGFuIG9wZXJhbmQgb2YgdGhlIGV4cHJlc3Npb24KICAgYnV0IGlzIG5vdyBub3QgbmVlZGVkIChlLmcuLCB3ZSBmb2xkZWQgT01JVFRFRCAqIDApLgoKICAgSWYgT01JVFRFRCBoYXMgc2lkZSBlZmZlY3RzLCB3ZSBtdXN0IGV2YWx1YXRlIGl0LiAgT3RoZXJ3aXNlLCBqdXN0IGRvCiAgIHRoZSBjb252ZXJzaW9uIG9mIFJFU1VMVCB0byBUWVBFLiAgKi8KCnRyZWUKb21pdF9vbmVfb3BlcmFuZCAodHJlZSB0eXBlLCB0cmVlIHJlc3VsdCwgdHJlZSBvbWl0dGVkKQp7CiAgdHJlZSB0ID0gZm9sZF9jb252ZXJ0ICh0eXBlLCByZXN1bHQpOwoKICBpZiAoVFJFRV9TSURFX0VGRkVDVFMgKG9taXR0ZWQpKQogICAgcmV0dXJuIGJ1aWxkIChDT01QT1VORF9FWFBSLCB0eXBlLCBvbWl0dGVkLCB0KTsKCiAgcmV0dXJuIG5vbl9sdmFsdWUgKHQpOwp9CgovKiBTaW1pbGFyLCBidXQgY2FsbCBwZWRhbnRpY19ub25fbHZhbHVlIGluc3RlYWQgb2Ygbm9uX2x2YWx1ZS4gICovCgpzdGF0aWMgdHJlZQpwZWRhbnRpY19vbWl0X29uZV9vcGVyYW5kICh0cmVlIHR5cGUsIHRyZWUgcmVzdWx0LCB0cmVlIG9taXR0ZWQpCnsKICB0cmVlIHQgPSBmb2xkX2NvbnZlcnQgKHR5cGUsIHJlc3VsdCk7CgogIGlmIChUUkVFX1NJREVfRUZGRUNUUyAob21pdHRlZCkpCiAgICByZXR1cm4gYnVpbGQgKENPTVBPVU5EX0VYUFIsIHR5cGUsIG9taXR0ZWQsIHQpOwoKICByZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZSAodCk7Cn0KDAovKiBSZXR1cm4gYSBzaW1wbGlmaWVkIHRyZWUgbm9kZSBmb3IgdGhlIHRydXRoLW5lZ2F0aW9uIG9mIEFSRy4gIFRoaXMKICAgbmV2ZXIgYWx0ZXJzIEFSRyBpdHNlbGYuICBXZSBhc3N1bWUgdGhhdCBBUkcgaXMgYW4gb3BlcmF0aW9uIHRoYXQKICAgcmV0dXJucyBhIHRydXRoIHZhbHVlICgwIG9yIDEpLiAgKi8KCnRyZWUKaW52ZXJ0X3RydXRodmFsdWUgKHRyZWUgYXJnKQp7CiAgdHJlZSB0eXBlID0gVFJFRV9UWVBFIChhcmcpOwogIGVudW0gdHJlZV9jb2RlIGNvZGUgPSBUUkVFX0NPREUgKGFyZyk7CgogIGlmIChjb2RlID09IEVSUk9SX01BUkspCiAgICByZXR1cm4gYXJnOwoKICAvKiBJZiB0aGlzIGlzIGEgY29tcGFyaXNvbiwgd2UgY2FuIHNpbXBseSBpbnZlcnQgaXQsIGV4Y2VwdCBmb3IKICAgICBmbG9hdGluZy1wb2ludCBub24tZXF1YWxpdHkgY29tcGFyaXNvbnMsIGluIHdoaWNoIGNhc2Ugd2UganVzdAogICAgIGVuY2xvc2UgYSBUUlVUSF9OT1RfRVhQUiBhcm91bmQgd2hhdCB3ZSBoYXZlLiAgKi8KCiAgaWYgKFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgPT0gJzwnKQogICAgewogICAgICBpZiAoRkxPQVRfVFlQRV9QIChUUkVFX1RZUEUgKFRSRUVfT1BFUkFORCAoYXJnLCAwKSkpCgkgICYmICFmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMKCSAgJiYgY29kZSAhPSBORV9FWFBSCgkgICYmIGNvZGUgIT0gRVFfRVhQUikKCXJldHVybiBidWlsZDEgKFRSVVRIX05PVF9FWFBSLCB0eXBlLCBhcmcpOwogICAgICBlbHNlCglyZXR1cm4gYnVpbGQgKGludmVydF90cmVlX2NvbXBhcmlzb24gKGNvZGUpLCB0eXBlLAoJCSAgICAgIFRSRUVfT1BFUkFORCAoYXJnLCAwKSwgVFJFRV9PUEVSQU5EIChhcmcsIDEpKTsKICAgIH0KCiAgc3dpdGNoIChjb2RlKQogICAgewogICAgY2FzZSBJTlRFR0VSX0NTVDoKICAgICAgcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgYnVpbGRfaW50XzIgKGludGVnZXJfemVyb3AgKGFyZyksIDApKTsKCiAgICBjYXNlIFRSVVRIX0FORF9FWFBSOgogICAgICByZXR1cm4gYnVpbGQgKFRSVVRIX09SX0VYUFIsIHR5cGUsCgkJICAgIGludmVydF90cnV0aHZhbHVlIChUUkVFX09QRVJBTkQgKGFyZywgMCkpLAoJCSAgICBpbnZlcnRfdHJ1dGh2YWx1ZSAoVFJFRV9PUEVSQU5EIChhcmcsIDEpKSk7CgogICAgY2FzZSBUUlVUSF9PUl9FWFBSOgogICAgICByZXR1cm4gYnVpbGQgKFRSVVRIX0FORF9FWFBSLCB0eXBlLAoJCSAgICBpbnZlcnRfdHJ1dGh2YWx1ZSAoVFJFRV9PUEVSQU5EIChhcmcsIDApKSwKCQkgICAgaW52ZXJ0X3RydXRodmFsdWUgKFRSRUVfT1BFUkFORCAoYXJnLCAxKSkpOwoKICAgIGNhc2UgVFJVVEhfWE9SX0VYUFI6CiAgICAgIC8qIEhlcmUgd2UgY2FuIGludmVydCBlaXRoZXIgb3BlcmFuZC4gIFdlIGludmVydCB0aGUgZmlyc3Qgb3BlcmFuZAoJIHVubGVzcyB0aGUgc2Vjb25kIG9wZXJhbmQgaXMgYSBUUlVUSF9OT1RfRVhQUiBpbiB3aGljaCBjYXNlIG91cgoJIHJlc3VsdCBpcyB0aGUgWE9SIG9mIHRoZSBmaXJzdCBvcGVyYW5kIHdpdGggdGhlIGluc2lkZSBvZiB0aGUKCSBuZWdhdGlvbiBvZiB0aGUgc2Vjb25kIG9wZXJhbmQuICAqLwoKICAgICAgaWYgKFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcsIDEpKSA9PSBUUlVUSF9OT1RfRVhQUikKCXJldHVybiBidWlsZCAoVFJVVEhfWE9SX0VYUFIsIHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnLCAwKSwKCQkgICAgICBUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoYXJnLCAxKSwgMCkpOwogICAgICBlbHNlCglyZXR1cm4gYnVpbGQgKFRSVVRIX1hPUl9FWFBSLCB0eXBlLAoJCSAgICAgIGludmVydF90cnV0aHZhbHVlIChUUkVFX09QRVJBTkQgKGFyZywgMCkpLAoJCSAgICAgIFRSRUVfT1BFUkFORCAoYXJnLCAxKSk7CgogICAgY2FzZSBUUlVUSF9BTkRJRl9FWFBSOgogICAgICByZXR1cm4gYnVpbGQgKFRSVVRIX09SSUZfRVhQUiwgdHlwZSwKCQkgICAgaW52ZXJ0X3RydXRodmFsdWUgKFRSRUVfT1BFUkFORCAoYXJnLCAwKSksCgkJICAgIGludmVydF90cnV0aHZhbHVlIChUUkVFX09QRVJBTkQgKGFyZywgMSkpKTsKCiAgICBjYXNlIFRSVVRIX09SSUZfRVhQUjoKICAgICAgcmV0dXJuIGJ1aWxkIChUUlVUSF9BTkRJRl9FWFBSLCB0eXBlLAoJCSAgICBpbnZlcnRfdHJ1dGh2YWx1ZSAoVFJFRV9PUEVSQU5EIChhcmcsIDApKSwKCQkgICAgaW52ZXJ0X3RydXRodmFsdWUgKFRSRUVfT1BFUkFORCAoYXJnLCAxKSkpOwoKICAgIGNhc2UgVFJVVEhfTk9UX0VYUFI6CiAgICAgIHJldHVybiBUUkVFX09QRVJBTkQgKGFyZywgMCk7CgogICAgY2FzZSBDT05EX0VYUFI6CiAgICAgIHJldHVybiBidWlsZCAoQ09ORF9FWFBSLCB0eXBlLCBUUkVFX09QRVJBTkQgKGFyZywgMCksCgkJICAgIGludmVydF90cnV0aHZhbHVlIChUUkVFX09QRVJBTkQgKGFyZywgMSkpLAoJCSAgICBpbnZlcnRfdHJ1dGh2YWx1ZSAoVFJFRV9PUEVSQU5EIChhcmcsIDIpKSk7CgogICAgY2FzZSBDT01QT1VORF9FWFBSOgogICAgICByZXR1cm4gYnVpbGQgKENPTVBPVU5EX0VYUFIsIHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnLCAwKSwKCQkgICAgaW52ZXJ0X3RydXRodmFsdWUgKFRSRUVfT1BFUkFORCAoYXJnLCAxKSkpOwoKICAgIGNhc2UgV0lUSF9SRUNPUkRfRVhQUjoKICAgICAgcmV0dXJuIGJ1aWxkIChXSVRIX1JFQ09SRF9FWFBSLCB0eXBlLAoJCSAgICBpbnZlcnRfdHJ1dGh2YWx1ZSAoVFJFRV9PUEVSQU5EIChhcmcsIDApKSwKCQkgICAgVFJFRV9PUEVSQU5EIChhcmcsIDEpKTsKCiAgICBjYXNlIE5PTl9MVkFMVUVfRVhQUjoKICAgICAgcmV0dXJuIGludmVydF90cnV0aHZhbHVlIChUUkVFX09QRVJBTkQgKGFyZywgMCkpOwoKICAgIGNhc2UgTk9QX0VYUFI6CiAgICBjYXNlIENPTlZFUlRfRVhQUjoKICAgIGNhc2UgRkxPQVRfRVhQUjoKICAgICAgcmV0dXJuIGJ1aWxkMSAoVFJFRV9DT0RFIChhcmcpLCB0eXBlLAoJCSAgICAgaW52ZXJ0X3RydXRodmFsdWUgKFRSRUVfT1BFUkFORCAoYXJnLCAwKSkpOwoKICAgIGNhc2UgQklUX0FORF9FWFBSOgogICAgICBpZiAoIWludGVnZXJfb25lcCAoVFJFRV9PUEVSQU5EIChhcmcsIDEpKSkKCWJyZWFrOwogICAgICByZXR1cm4gYnVpbGQgKEVRX0VYUFIsIHR5cGUsIGFyZywKCQkgICAgZm9sZF9jb252ZXJ0ICh0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSkpOwoKICAgIGNhc2UgU0FWRV9FWFBSOgogICAgICByZXR1cm4gYnVpbGQxIChUUlVUSF9OT1RfRVhQUiwgdHlwZSwgYXJnKTsKCiAgICBjYXNlIENMRUFOVVBfUE9JTlRfRVhQUjoKICAgICAgcmV0dXJuIGJ1aWxkMSAoQ0xFQU5VUF9QT0lOVF9FWFBSLCB0eXBlLAoJCSAgICAgaW52ZXJ0X3RydXRodmFsdWUgKFRSRUVfT1BFUkFORCAoYXJnLCAwKSkpOwoKICAgIGRlZmF1bHQ6CiAgICAgIGJyZWFrOwogICAgfQogIGlmIChUUkVFX0NPREUgKFRSRUVfVFlQRSAoYXJnKSkgIT0gQk9PTEVBTl9UWVBFKQogICAgYWJvcnQgKCk7CiAgcmV0dXJuIGJ1aWxkMSAoVFJVVEhfTk9UX0VYUFIsIHR5cGUsIGFyZyk7Cn0KCi8qIEdpdmVuIGEgYml0LXdpc2Ugb3BlcmF0aW9uIENPREUgYXBwbGllZCB0byBBUkcwIGFuZCBBUkcxLCBzZWUgaWYgYm90aAogICBvcGVyYW5kcyBhcmUgYW5vdGhlciBiaXQtd2lzZSBvcGVyYXRpb24gd2l0aCBhIGNvbW1vbiBpbnB1dC4gIElmIHNvLAogICBkaXN0cmlidXRlIHRoZSBiaXQgb3BlcmF0aW9ucyB0byBzYXZlIGFuIG9wZXJhdGlvbiBhbmQgcG9zc2libHkgdHdvIGlmCiAgIGNvbnN0YW50cyBhcmUgaW52b2x2ZWQuICBGb3IgZXhhbXBsZSwgY29udmVydAoJKEEgfCBCKSAmIChBIHwgQykgaW50byBBIHwgKEIgJiBDKQogICBGdXJ0aGVyIHNpbXBsaWZpY2F0aW9uIHdpbGwgb2NjdXIgaWYgQiBhbmQgQyBhcmUgY29uc3RhbnRzLgoKICAgSWYgdGhpcyBvcHRpbWl6YXRpb24gY2Fubm90IGJlIGRvbmUsIDAgd2lsbCBiZSByZXR1cm5lZC4gICovCgpzdGF0aWMgdHJlZQpkaXN0cmlidXRlX2JpdF9leHByIChlbnVtIHRyZWVfY29kZSBjb2RlLCB0cmVlIHR5cGUsIHRyZWUgYXJnMCwgdHJlZSBhcmcxKQp7CiAgdHJlZSBjb21tb247CiAgdHJlZSBsZWZ0LCByaWdodDsKCiAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgIT0gVFJFRV9DT0RFIChhcmcxKQogICAgICB8fCBUUkVFX0NPREUgKGFyZzApID09IGNvZGUKICAgICAgfHwgKFRSRUVfQ09ERSAoYXJnMCkgIT0gQklUX0FORF9FWFBSCgkgICYmIFRSRUVfQ09ERSAoYXJnMCkgIT0gQklUX0lPUl9FWFBSKSkKICAgIHJldHVybiAwOwoKICBpZiAob3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLCBUUkVFX09QRVJBTkQgKGFyZzEsIDApLCAwKSkKICAgIHsKICAgICAgY29tbW9uID0gVFJFRV9PUEVSQU5EIChhcmcwLCAwKTsKICAgICAgbGVmdCA9IFRSRUVfT1BFUkFORCAoYXJnMCwgMSk7CiAgICAgIHJpZ2h0ID0gVFJFRV9PUEVSQU5EIChhcmcxLCAxKTsKICAgIH0KICBlbHNlIGlmIChvcGVyYW5kX2VxdWFsX3AgKFRSRUVfT1BFUkFORCAoYXJnMCwgMCksIFRSRUVfT1BFUkFORCAoYXJnMSwgMSksIDApKQogICAgewogICAgICBjb21tb24gPSBUUkVFX09QRVJBTkQgKGFyZzAsIDApOwogICAgICBsZWZ0ID0gVFJFRV9PUEVSQU5EIChhcmcwLCAxKTsKICAgICAgcmlnaHQgPSBUUkVFX09QRVJBTkQgKGFyZzEsIDApOwogICAgfQogIGVsc2UgaWYgKG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwgVFJFRV9PUEVSQU5EIChhcmcxLCAwKSwgMCkpCiAgICB7CiAgICAgIGNvbW1vbiA9IFRSRUVfT1BFUkFORCAoYXJnMCwgMSk7CiAgICAgIGxlZnQgPSBUUkVFX09QRVJBTkQgKGFyZzAsIDApOwogICAgICByaWdodCA9IFRSRUVfT1BFUkFORCAoYXJnMSwgMSk7CiAgICB9CiAgZWxzZSBpZiAob3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpLCBUUkVFX09QRVJBTkQgKGFyZzEsIDEpLCAwKSkKICAgIHsKICAgICAgY29tbW9uID0gVFJFRV9PUEVSQU5EIChhcmcwLCAxKTsKICAgICAgbGVmdCA9IFRSRUVfT1BFUkFORCAoYXJnMCwgMCk7CiAgICAgIHJpZ2h0ID0gVFJFRV9PUEVSQU5EIChhcmcxLCAwKTsKICAgIH0KICBlbHNlCiAgICByZXR1cm4gMDsKCiAgcmV0dXJuIGZvbGQgKGJ1aWxkIChUUkVFX0NPREUgKGFyZzApLCB0eXBlLCBjb21tb24sCgkJICAgICAgZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIGxlZnQsIHJpZ2h0KSkpKTsKfQoMCi8qIFJldHVybiBhIEJJVF9GSUVMRF9SRUYgb2YgdHlwZSBUWVBFIHRvIHJlZmVyIHRvIEJJVFNJWkUgYml0cyBvZiBJTk5FUgogICBzdGFydGluZyBhdCBCSVRQT1MuICBUaGUgZmllbGQgaXMgdW5zaWduZWQgaWYgVU5TSUdORURQIGlzIG5vbnplcm8uICAqLwoKc3RhdGljIHRyZWUKbWFrZV9iaXRfZmllbGRfcmVmICh0cmVlIGlubmVyLCB0cmVlIHR5cGUsIGludCBiaXRzaXplLCBpbnQgYml0cG9zLAoJCSAgICBpbnQgdW5zaWduZWRwKQp7CiAgdHJlZSByZXN1bHQgPSBidWlsZCAoQklUX0ZJRUxEX1JFRiwgdHlwZSwgaW5uZXIsCgkJICAgICAgIHNpemVfaW50IChiaXRzaXplKSwgYml0c2l6ZV9pbnQgKGJpdHBvcykpOwoKICBUUkVFX1VOU0lHTkVEIChyZXN1bHQpID0gdW5zaWduZWRwOwoKICByZXR1cm4gcmVzdWx0Owp9CgovKiBPcHRpbWl6ZSBhIGJpdC1maWVsZCBjb21wYXJlLgoKICAgVGhlcmUgYXJlIHR3byBjYXNlczogIEZpcnN0IGlzIGEgY29tcGFyZSBhZ2FpbnN0IGEgY29uc3RhbnQgYW5kIHRoZQogICBzZWNvbmQgaXMgYSBjb21wYXJpc29uIG9mIHR3byBpdGVtcyB3aGVyZSB0aGUgZmllbGRzIGFyZSBhdCB0aGUgc2FtZQogICBiaXQgcG9zaXRpb24gcmVsYXRpdmUgdG8gdGhlIHN0YXJ0IG9mIGEgY2h1bmsgKGJ5dGUsIGhhbGZ3b3JkLCB3b3JkKQogICBsYXJnZSBlbm91Z2ggdG8gY29udGFpbiBpdC4gIEluIHRoZXNlIGNhc2VzIHdlIGNhbiBhdm9pZCB0aGUgc2hpZnQKICAgaW1wbGljaXQgaW4gYml0ZmllbGQgZXh0cmFjdGlvbnMuCgogICBGb3IgY29uc3RhbnRzLCB3ZSBlbWl0IGEgY29tcGFyZSBvZiB0aGUgc2hpZnRlZCBjb25zdGFudCB3aXRoIHRoZQogICBCSVRfQU5EX0VYUFIgb2YgYSBtYXNrIGFuZCBhIGJ5dGUsIGhhbGZ3b3JkLCBvciB3b3JkIG9mIHRoZSBvcGVyYW5kIGJlaW5nCiAgIGNvbXBhcmVkLiAgRm9yIHR3byBmaWVsZHMgYXQgdGhlIHNhbWUgcG9zaXRpb24sIHdlIGRvIHRoZSBBTkRzIHdpdGggdGhlCiAgIHNpbWlsYXIgbWFzayBhbmQgY29tcGFyZSB0aGUgcmVzdWx0IG9mIHRoZSBBTkRzLgoKICAgQ09ERSBpcyB0aGUgY29tcGFyaXNvbiBjb2RlLCBrbm93biB0byBiZSBlaXRoZXIgTkVfRVhQUiBvciBFUV9FWFBSLgogICBDT01QQVJFX1RZUEUgaXMgdGhlIHR5cGUgb2YgdGhlIGNvbXBhcmlzb24sIGFuZCBMSFMgYW5kIFJIUwogICBhcmUgdGhlIGxlZnQgYW5kIHJpZ2h0IG9wZXJhbmRzIG9mIHRoZSBjb21wYXJpc29uLCByZXNwZWN0aXZlbHkuCgogICBJZiB0aGUgb3B0aW1pemF0aW9uIGRlc2NyaWJlZCBhYm92ZSBjYW4gYmUgZG9uZSwgd2UgcmV0dXJuIHRoZSByZXN1bHRpbmcKICAgdHJlZS4gIE90aGVyd2lzZSB3ZSByZXR1cm4gemVyby4gICovCgpzdGF0aWMgdHJlZQpvcHRpbWl6ZV9iaXRfZmllbGRfY29tcGFyZSAoZW51bSB0cmVlX2NvZGUgY29kZSwgdHJlZSBjb21wYXJlX3R5cGUsCgkJCSAgICB0cmVlIGxocywgdHJlZSByaHMpCnsKICBIT1NUX1dJREVfSU5UIGxiaXRwb3MsIGxiaXRzaXplLCByYml0cG9zLCByYml0c2l6ZSwgbmJpdHBvcywgbmJpdHNpemU7CiAgdHJlZSB0eXBlID0gVFJFRV9UWVBFIChsaHMpOwogIHRyZWUgc2lnbmVkX3R5cGUsIHVuc2lnbmVkX3R5cGU7CiAgaW50IGNvbnN0X3AgPSBUUkVFX0NPREUgKHJocykgPT0gSU5URUdFUl9DU1Q7CiAgZW51bSBtYWNoaW5lX21vZGUgbG1vZGUsIHJtb2RlLCBubW9kZTsKICBpbnQgbHVuc2lnbmVkcCwgcnVuc2lnbmVkcDsKICBpbnQgbHZvbGF0aWxlcCA9IDAsIHJ2b2xhdGlsZXAgPSAwOwogIHRyZWUgbGlubmVyLCByaW5uZXIgPSBOVUxMX1RSRUU7CiAgdHJlZSBtYXNrOwogIHRyZWUgb2Zmc2V0OwoKICAvKiBHZXQgYWxsIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZXh0cmFjdGlvbnMgYmVpbmcgZG9uZS4gIElmIHRoZSBiaXQgc2l6ZQogICAgIGlmIHRoZSBzYW1lIGFzIHRoZSBzaXplIG9mIHRoZSB1bmRlcmx5aW5nIG9iamVjdCwgd2UgYXJlbid0IGRvaW5nIGFuCiAgICAgZXh0cmFjdGlvbiBhdCBhbGwgYW5kIHNvIGNhbiBkbyBub3RoaW5nLiAgV2UgYWxzbyBkb24ndCB3YW50IHRvCiAgICAgZG8gYW55dGhpbmcgaWYgdGhlIGlubmVyIGV4cHJlc3Npb24gaXMgYSBQTEFDRUhPTERFUl9FWFBSIHNpbmNlIHdlCiAgICAgdGhlbiB3aWxsIG5vIGxvbmdlciBiZSBhYmxlIHRvIHJlcGxhY2UgaXQuICAqLwogIGxpbm5lciA9IGdldF9pbm5lcl9yZWZlcmVuY2UgKGxocywgJmxiaXRzaXplLCAmbGJpdHBvcywgJm9mZnNldCwgJmxtb2RlLAoJCQkJJmx1bnNpZ25lZHAsICZsdm9sYXRpbGVwKTsKICBpZiAobGlubmVyID09IGxocyB8fCBsYml0c2l6ZSA9PSBHRVRfTU9ERV9CSVRTSVpFIChsbW9kZSkgfHwgbGJpdHNpemUgPCAwCiAgICAgIHx8IG9mZnNldCAhPSAwIHx8IFRSRUVfQ09ERSAobGlubmVyKSA9PSBQTEFDRUhPTERFUl9FWFBSKQogICAgcmV0dXJuIDA7CgogaWYgKCFjb25zdF9wKQogICB7CiAgICAgLyogSWYgdGhpcyBpcyBub3QgYSBjb25zdGFudCwgd2UgY2FuIG9ubHkgZG8gc29tZXRoaW5nIGlmIGJpdCBwb3NpdGlvbnMsCglzaXplcywgYW5kIHNpZ25lZG5lc3MgYXJlIHRoZSBzYW1lLiAgKi8KICAgICByaW5uZXIgPSBnZXRfaW5uZXJfcmVmZXJlbmNlIChyaHMsICZyYml0c2l6ZSwgJnJiaXRwb3MsICZvZmZzZXQsICZybW9kZSwKCQkJCSAgICZydW5zaWduZWRwLCAmcnZvbGF0aWxlcCk7CgogICAgIGlmIChyaW5uZXIgPT0gcmhzIHx8IGxiaXRwb3MgIT0gcmJpdHBvcyB8fCBsYml0c2l6ZSAhPSByYml0c2l6ZQoJIHx8IGx1bnNpZ25lZHAgIT0gcnVuc2lnbmVkcCB8fCBvZmZzZXQgIT0gMAoJIHx8IFRSRUVfQ09ERSAocmlubmVyKSA9PSBQTEFDRUhPTERFUl9FWFBSKQogICAgICAgcmV0dXJuIDA7CiAgIH0KCiAgLyogU2VlIGlmIHdlIGNhbiBmaW5kIGEgbW9kZSB0byByZWZlciB0byB0aGlzIGZpZWxkLiAgV2Ugc2hvdWxkIGJlIGFibGUgdG8sCiAgICAgYnV0IGZhaWwgaWYgd2UgY2FuJ3QuICAqLwogIG5tb2RlID0gZ2V0X2Jlc3RfbW9kZSAobGJpdHNpemUsIGxiaXRwb3MsCgkJCSBjb25zdF9wID8gVFlQRV9BTElHTiAoVFJFRV9UWVBFIChsaW5uZXIpKQoJCQkgOiBNSU4gKFRZUEVfQUxJR04gKFRSRUVfVFlQRSAobGlubmVyKSksCgkJCQlUWVBFX0FMSUdOIChUUkVFX1RZUEUgKHJpbm5lcikpKSwKCQkJIHdvcmRfbW9kZSwgbHZvbGF0aWxlcCB8fCBydm9sYXRpbGVwKTsKICBpZiAobm1vZGUgPT0gVk9JRG1vZGUpCiAgICByZXR1cm4gMDsKCiAgLyogU2V0IHNpZ25lZCBhbmQgdW5zaWduZWQgdHlwZXMgb2YgdGhlIHByZWNpc2lvbiBvZiB0aGlzIG1vZGUgZm9yIHRoZQogICAgIHNoaWZ0cyBiZWxvdy4gICovCiAgc2lnbmVkX3R5cGUgPSAoKmxhbmdfaG9va3MudHlwZXMudHlwZV9mb3JfbW9kZSkgKG5tb2RlLCAwKTsKICB1bnNpZ25lZF90eXBlID0gKCpsYW5nX2hvb2tzLnR5cGVzLnR5cGVfZm9yX21vZGUpIChubW9kZSwgMSk7CgogIC8qIENvbXB1dGUgdGhlIGJpdCBwb3NpdGlvbiBhbmQgc2l6ZSBmb3IgdGhlIG5ldyByZWZlcmVuY2UgYW5kIG91ciBvZmZzZXQKICAgICB3aXRoaW4gaXQuIElmIHRoZSBuZXcgcmVmZXJlbmNlIGlzIHRoZSBzYW1lIHNpemUgYXMgdGhlIG9yaWdpbmFsLCB3ZQogICAgIHdvbid0IG9wdGltaXplIGFueXRoaW5nLCBzbyByZXR1cm4gemVyby4gICovCiAgbmJpdHNpemUgPSBHRVRfTU9ERV9CSVRTSVpFIChubW9kZSk7CiAgbmJpdHBvcyA9IGxiaXRwb3MgJiB+IChuYml0c2l6ZSAtIDEpOwogIGxiaXRwb3MgLT0gbmJpdHBvczsKICBpZiAobmJpdHNpemUgPT0gbGJpdHNpemUpCiAgICByZXR1cm4gMDsKCiAgaWYgKEJZVEVTX0JJR19FTkRJQU4pCiAgICBsYml0cG9zID0gbmJpdHNpemUgLSBsYml0c2l6ZSAtIGxiaXRwb3M7CgogIC8qIE1ha2UgdGhlIG1hc2sgdG8gYmUgdXNlZCBhZ2FpbnN0IHRoZSBleHRyYWN0ZWQgZmllbGQuICAqLwogIG1hc2sgPSBidWlsZF9pbnRfMiAofjAsIH4wKTsKICBUUkVFX1RZUEUgKG1hc2spID0gdW5zaWduZWRfdHlwZTsKICBmb3JjZV9maXRfdHlwZSAobWFzaywgMCk7CiAgbWFzayA9IGZvbGRfY29udmVydCAodW5zaWduZWRfdHlwZSwgbWFzayk7CiAgbWFzayA9IGNvbnN0X2Jpbm9wIChMU0hJRlRfRVhQUiwgbWFzaywgc2l6ZV9pbnQgKG5iaXRzaXplIC0gbGJpdHNpemUpLCAwKTsKICBtYXNrID0gY29uc3RfYmlub3AgKFJTSElGVF9FWFBSLCBtYXNrLAoJCSAgICAgIHNpemVfaW50IChuYml0c2l6ZSAtIGxiaXRzaXplIC0gbGJpdHBvcyksIDApOwoKICBpZiAoISBjb25zdF9wKQogICAgLyogSWYgbm90IGNvbXBhcmluZyB3aXRoIGNvbnN0YW50LCBqdXN0IHJld29yayB0aGUgY29tcGFyaXNvbgogICAgICAgYW5kIHJldHVybi4gICovCiAgICByZXR1cm4gYnVpbGQgKGNvZGUsIGNvbXBhcmVfdHlwZSwKCQkgIGJ1aWxkIChCSVRfQU5EX0VYUFIsIHVuc2lnbmVkX3R5cGUsCgkJCSBtYWtlX2JpdF9maWVsZF9yZWYgKGxpbm5lciwgdW5zaWduZWRfdHlwZSwKCQkJCQkgICAgIG5iaXRzaXplLCBuYml0cG9zLCAxKSwKCQkJIG1hc2spLAoJCSAgYnVpbGQgKEJJVF9BTkRfRVhQUiwgdW5zaWduZWRfdHlwZSwKCQkJIG1ha2VfYml0X2ZpZWxkX3JlZiAocmlubmVyLCB1bnNpZ25lZF90eXBlLAoJCQkJCSAgICAgbmJpdHNpemUsIG5iaXRwb3MsIDEpLAoJCQkgbWFzaykpOwoKICAvKiBPdGhlcndpc2UsIHdlIGFyZSBoYW5kbGluZyB0aGUgY29uc3RhbnQgY2FzZS4gU2VlIGlmIHRoZSBjb25zdGFudCBpcyB0b28KICAgICBiaWcgZm9yIHRoZSBmaWVsZC4gIFdhcm4gYW5kIHJldHVybiBhIHRyZWUgb2YgZm9yIDAgKGZhbHNlKSBpZiBzby4gIFdlIGRvCiAgICAgdGhpcyBub3Qgb25seSBmb3IgaXRzIG93biBzYWtlLCBidXQgdG8gYXZvaWQgaGF2aW5nIHRvIHRlc3QgZm9yIHRoaXMKICAgICBlcnJvciBjYXNlIGJlbG93LiAgSWYgd2UgZGlkbid0LCB3ZSBtaWdodCBnZW5lcmF0ZSB3cm9uZyBjb2RlLgoKICAgICBGb3IgdW5zaWduZWQgZmllbGRzLCB0aGUgY29uc3RhbnQgc2hpZnRlZCByaWdodCBieSB0aGUgZmllbGQgbGVuZ3RoIHNob3VsZAogICAgIGJlIGFsbCB6ZXJvLiAgRm9yIHNpZ25lZCBmaWVsZHMsIHRoZSBoaWdoLW9yZGVyIGJpdHMgc2hvdWxkIGFncmVlIHdpdGgKICAgICB0aGUgc2lnbiBiaXQuICAqLwoKICBpZiAobHVuc2lnbmVkcCkKICAgIHsKICAgICAgaWYgKCEgaW50ZWdlcl96ZXJvcCAoY29uc3RfYmlub3AgKFJTSElGVF9FWFBSLAoJCQkJCWZvbGRfY29udmVydCAodW5zaWduZWRfdHlwZSwgcmhzKSwKCQkJCQlzaXplX2ludCAobGJpdHNpemUpLCAwKSkpCgl7CgkgIHdhcm5pbmcgKCJjb21wYXJpc29uIGlzIGFsd2F5cyAlZCBkdWUgdG8gd2lkdGggb2YgYml0LWZpZWxkIiwKCQkgICBjb2RlID09IE5FX0VYUFIpOwoJICByZXR1cm4gZm9sZF9jb252ZXJ0IChjb21wYXJlX3R5cGUsCgkJCSAgICAgICAoY29kZSA9PSBORV9FWFBSCgkJCQk/IGludGVnZXJfb25lX25vZGUgOiBpbnRlZ2VyX3plcm9fbm9kZSkpOwoJfQogICAgfQogIGVsc2UKICAgIHsKICAgICAgdHJlZSB0ZW0gPSBjb25zdF9iaW5vcCAoUlNISUZUX0VYUFIsIGZvbGRfY29udmVydCAoc2lnbmVkX3R5cGUsIHJocyksCgkJCSAgICAgIHNpemVfaW50IChsYml0c2l6ZSAtIDEpLCAwKTsKICAgICAgaWYgKCEgaW50ZWdlcl96ZXJvcCAodGVtKSAmJiAhIGludGVnZXJfYWxsX29uZXNwICh0ZW0pKQoJewoJICB3YXJuaW5nICgiY29tcGFyaXNvbiBpcyBhbHdheXMgJWQgZHVlIHRvIHdpZHRoIG9mIGJpdC1maWVsZCIsCgkJICAgY29kZSA9PSBORV9FWFBSKTsKCSAgcmV0dXJuIGZvbGRfY29udmVydCAoY29tcGFyZV90eXBlLAoJCQkgICAgICAgKGNvZGUgPT0gTkVfRVhQUgoJCQkJPyBpbnRlZ2VyX29uZV9ub2RlIDogaW50ZWdlcl96ZXJvX25vZGUpKTsKCX0KICAgIH0KCiAgLyogU2luZ2xlLWJpdCBjb21wYXJlcyBzaG91bGQgYWx3YXlzIGJlIGFnYWluc3QgemVyby4gICovCiAgaWYgKGxiaXRzaXplID09IDEgJiYgISBpbnRlZ2VyX3plcm9wIChyaHMpKQogICAgewogICAgICBjb2RlID0gY29kZSA9PSBFUV9FWFBSID8gTkVfRVhQUiA6IEVRX0VYUFI7CiAgICAgIHJocyA9IGZvbGRfY29udmVydCAodHlwZSwgaW50ZWdlcl96ZXJvX25vZGUpOwogICAgfQoKICAvKiBNYWtlIGEgbmV3IGJpdGZpZWxkIHJlZmVyZW5jZSwgc2hpZnQgdGhlIGNvbnN0YW50IG92ZXIgdGhlCiAgICAgYXBwcm9wcmlhdGUgbnVtYmVyIG9mIGJpdHMgYW5kIG1hc2sgaXQgd2l0aCB0aGUgY29tcHV0ZWQgbWFzawogICAgIChpbiBjYXNlIHRoaXMgd2FzIGEgc2lnbmVkIGZpZWxkKS4gIElmIHdlIGNoYW5nZWQgaXQsIG1ha2UgYSBuZXcgb25lLiAgKi8KICBsaHMgPSBtYWtlX2JpdF9maWVsZF9yZWYgKGxpbm5lciwgdW5zaWduZWRfdHlwZSwgbmJpdHNpemUsIG5iaXRwb3MsIDEpOwogIGlmIChsdm9sYXRpbGVwKQogICAgewogICAgICBUUkVFX1NJREVfRUZGRUNUUyAobGhzKSA9IDE7CiAgICAgIFRSRUVfVEhJU19WT0xBVElMRSAobGhzKSA9IDE7CiAgICB9CgogIHJocyA9IGZvbGQgKGNvbnN0X2Jpbm9wIChCSVRfQU5EX0VYUFIsCgkJCSAgIGNvbnN0X2Jpbm9wIChMU0hJRlRfRVhQUiwKCQkJCQlmb2xkX2NvbnZlcnQgKHVuc2lnbmVkX3R5cGUsIHJocyksCgkJCQkJc2l6ZV9pbnQgKGxiaXRwb3MpLCAwKSwKCQkJICAgbWFzaywgMCkpOwoKICByZXR1cm4gYnVpbGQgKGNvZGUsIGNvbXBhcmVfdHlwZSwKCQlidWlsZCAoQklUX0FORF9FWFBSLCB1bnNpZ25lZF90eXBlLCBsaHMsIG1hc2spLAoJCXJocyk7Cn0KDAovKiBTdWJyb3V0aW5lIGZvciBmb2xkX3RydXRob3A6IGRlY29kZSBhIGZpZWxkIHJlZmVyZW5jZS4KCiAgIElmIEVYUCBpcyBhIGNvbXBhcmlzb24gcmVmZXJlbmNlLCB3ZSByZXR1cm4gdGhlIGlubmVybW9zdCByZWZlcmVuY2UuCgogICAqUEJJVFNJWkUgaXMgc2V0IHRvIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgcmVmZXJlbmNlLCAqUEJJVFBPUyBpcwogICBzZXQgdG8gdGhlIHN0YXJ0aW5nIGJpdCBudW1iZXIuCgogICBJZiB0aGUgaW5uZXJtb3N0IGZpZWxkIGNhbiBiZSBjb21wbGV0ZWx5IGNvbnRhaW5lZCBpbiBhIG1vZGUtc2l6ZWQKICAgdW5pdCwgKlBNT0RFIGlzIHNldCB0byB0aGF0IG1vZGUuICBPdGhlcndpc2UsIGl0IGlzIHNldCB0byBWT0lEbW9kZS4KCiAgICpQVk9MQVRJTEVQIGlzIHNldCB0byAxIGlmIHRoZSBhbnkgZXhwcmVzc2lvbiBlbmNvdW50ZXJlZCBpcyB2b2xhdGlsZTsKICAgb3RoZXJ3aXNlIGl0IGlzIG5vdCBjaGFuZ2VkLgoKICAgKlBVTlNJR05FRFAgaXMgc2V0IHRvIHRoZSBzaWduZWRuZXNzIG9mIHRoZSBmaWVsZC4KCiAgICpQTUFTSyBpcyBzZXQgdG8gdGhlIG1hc2sgdXNlZC4gIFRoaXMgaXMgZWl0aGVyIGNvbnRhaW5lZCBpbiBhCiAgIEJJVF9BTkRfRVhQUiBvciBkZXJpdmVkIGZyb20gdGhlIHdpZHRoIG9mIHRoZSBmaWVsZC4KCiAgICpQQU5EX01BU0sgaXMgc2V0IHRvIHRoZSBtYXNrIGZvdW5kIGluIGEgQklUX0FORF9FWFBSLCBpZiBhbnkuCgogICBSZXR1cm4gMCBpZiB0aGlzIGlzIG5vdCBhIGNvbXBvbmVudCByZWZlcmVuY2Ugb3IgaXMgb25lIHRoYXQgd2UgY2FuJ3QKICAgZG8gYW55dGhpbmcgd2l0aC4gICovCgpzdGF0aWMgdHJlZQpkZWNvZGVfZmllbGRfcmVmZXJlbmNlICh0cmVlIGV4cCwgSE9TVF9XSURFX0lOVCAqcGJpdHNpemUsCgkJCUhPU1RfV0lERV9JTlQgKnBiaXRwb3MsIGVudW0gbWFjaGluZV9tb2RlICpwbW9kZSwKCQkJaW50ICpwdW5zaWduZWRwLCBpbnQgKnB2b2xhdGlsZXAsCgkJCXRyZWUgKnBtYXNrLCB0cmVlICpwYW5kX21hc2spCnsKICB0cmVlIG91dGVyX3R5cGUgPSAwOwogIHRyZWUgYW5kX21hc2sgPSAwOwogIHRyZWUgbWFzaywgaW5uZXIsIG9mZnNldDsKICB0cmVlIHVuc2lnbmVkX3R5cGU7CiAgdW5zaWduZWQgaW50IHByZWNpc2lvbjsKCiAgLyogQWxsIHRoZSBvcHRpbWl6YXRpb25zIHVzaW5nIHRoaXMgZnVuY3Rpb24gYXNzdW1lIGludGVnZXIgZmllbGRzLgogICAgIFRoZXJlIGFyZSBwcm9ibGVtcyB3aXRoIEZQIGZpZWxkcyBzaW5jZSB0aGUgdHlwZV9mb3Jfc2l6ZSBjYWxsCiAgICAgYmVsb3cgY2FuIGZhaWwgZm9yLCBlLmcuLCBYRm1vZGUuICAqLwogIGlmICghIElOVEVHUkFMX1RZUEVfUCAoVFJFRV9UWVBFIChleHApKSkKICAgIHJldHVybiAwOwoKICAvKiBXZSBhcmUgaW50ZXJlc3RlZCBpbiB0aGUgYmFyZSBhcnJhbmdlbWVudCBvZiBiaXRzLCBzbyBzdHJpcCBldmVyeXRoaW5nCiAgICAgdGhhdCBkb2Vzbid0IGFmZmVjdCB0aGUgbWFjaGluZSBtb2RlLiAgSG93ZXZlciwgcmVjb3JkIHRoZSB0eXBlIG9mIHRoZQogICAgIG91dGVybW9zdCBleHByZXNzaW9uIGlmIGl0IG1heSBtYXR0ZXIgYmVsb3cuICAqLwogIGlmIChUUkVFX0NPREUgKGV4cCkgPT0gTk9QX0VYUFIKICAgICAgfHwgVFJFRV9DT0RFIChleHApID09IENPTlZFUlRfRVhQUgogICAgICB8fCBUUkVFX0NPREUgKGV4cCkgPT0gTk9OX0xWQUxVRV9FWFBSKQogICAgb3V0ZXJfdHlwZSA9IFRSRUVfVFlQRSAoZXhwKTsKICBTVFJJUF9OT1BTIChleHApOwoKICBpZiAoVFJFRV9DT0RFIChleHApID09IEJJVF9BTkRfRVhQUikKICAgIHsKICAgICAgYW5kX21hc2sgPSBUUkVFX09QRVJBTkQgKGV4cCwgMSk7CiAgICAgIGV4cCA9IFRSRUVfT1BFUkFORCAoZXhwLCAwKTsKICAgICAgU1RSSVBfTk9QUyAoZXhwKTsgU1RSSVBfTk9QUyAoYW5kX21hc2spOwogICAgICBpZiAoVFJFRV9DT0RFIChhbmRfbWFzaykgIT0gSU5URUdFUl9DU1QpCglyZXR1cm4gMDsKICAgIH0KCiAgaW5uZXIgPSBnZXRfaW5uZXJfcmVmZXJlbmNlIChleHAsIHBiaXRzaXplLCBwYml0cG9zLCAmb2Zmc2V0LCBwbW9kZSwKCQkJICAgICAgIHB1bnNpZ25lZHAsIHB2b2xhdGlsZXApOwogIGlmICgoaW5uZXIgPT0gZXhwICYmIGFuZF9tYXNrID09IDApCiAgICAgIHx8ICpwYml0c2l6ZSA8IDAgfHwgb2Zmc2V0ICE9IDAKICAgICAgfHwgVFJFRV9DT0RFIChpbm5lcikgPT0gUExBQ0VIT0xERVJfRVhQUikKICAgIHJldHVybiAwOwoKICAvKiBJZiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIHJlZmVyZW5jZSBpcyB0aGUgc2FtZSBhcyB0aGUgYml0c2l6ZSBvZgogICAgIHRoZSBvdXRlciB0eXBlLCB0aGVuIHRoZSBvdXRlciB0eXBlIGdpdmVzIHRoZSBzaWduZWRuZXNzLiBPdGhlcndpc2UKICAgICAoaW4gY2FzZSBvZiBhIHNtYWxsIGJpdGZpZWxkKSB0aGUgc2lnbmVkbmVzcyBpcyB1bmNoYW5nZWQuICAqLwogIGlmIChvdXRlcl90eXBlICYmICpwYml0c2l6ZSA9PSB0cmVlX2xvd19jc3QgKFRZUEVfU0laRSAob3V0ZXJfdHlwZSksIDEpKQogICAgKnB1bnNpZ25lZHAgPSBUUkVFX1VOU0lHTkVEIChvdXRlcl90eXBlKTsKCiAgLyogQ29tcHV0ZSB0aGUgbWFzayB0byBhY2Nlc3MgdGhlIGJpdGZpZWxkLiAgKi8KICB1bnNpZ25lZF90eXBlID0gKCpsYW5nX2hvb2tzLnR5cGVzLnR5cGVfZm9yX3NpemUpICgqcGJpdHNpemUsIDEpOwogIHByZWNpc2lvbiA9IFRZUEVfUFJFQ0lTSU9OICh1bnNpZ25lZF90eXBlKTsKCiAgbWFzayA9IGJ1aWxkX2ludF8yICh+MCwgfjApOwogIFRSRUVfVFlQRSAobWFzaykgPSB1bnNpZ25lZF90eXBlOwogIGZvcmNlX2ZpdF90eXBlIChtYXNrLCAwKTsKICBtYXNrID0gY29uc3RfYmlub3AgKExTSElGVF9FWFBSLCBtYXNrLCBzaXplX2ludCAocHJlY2lzaW9uIC0gKnBiaXRzaXplKSwgMCk7CiAgbWFzayA9IGNvbnN0X2Jpbm9wIChSU0hJRlRfRVhQUiwgbWFzaywgc2l6ZV9pbnQgKHByZWNpc2lvbiAtICpwYml0c2l6ZSksIDApOwoKICAvKiBNZXJnZSBpdCB3aXRoIHRoZSBtYXNrIHdlIGZvdW5kIGluIHRoZSBCSVRfQU5EX0VYUFIsIGlmIGFueS4gICovCiAgaWYgKGFuZF9tYXNrICE9IDApCiAgICBtYXNrID0gZm9sZCAoYnVpbGQgKEJJVF9BTkRfRVhQUiwgdW5zaWduZWRfdHlwZSwKCQkJZm9sZF9jb252ZXJ0ICh1bnNpZ25lZF90eXBlLCBhbmRfbWFzayksIG1hc2spKTsKCiAgKnBtYXNrID0gbWFzazsKICAqcGFuZF9tYXNrID0gYW5kX21hc2s7CiAgcmV0dXJuIGlubmVyOwp9CgovKiBSZXR1cm4gbm9uemVybyBpZiBNQVNLIHJlcHJlc2VudHMgYSBtYXNrIG9mIFNJWkUgb25lcyBpbiB0aGUgbG93LW9yZGVyCiAgIGJpdCBwb3NpdGlvbnMuICAqLwoKc3RhdGljIGludAphbGxfb25lc19tYXNrX3AgKHRyZWUgbWFzaywgaW50IHNpemUpCnsKICB0cmVlIHR5cGUgPSBUUkVFX1RZUEUgKG1hc2spOwogIHVuc2lnbmVkIGludCBwcmVjaXNpb24gPSBUWVBFX1BSRUNJU0lPTiAodHlwZSk7CiAgdHJlZSB0bWFzazsKCiAgdG1hc2sgPSBidWlsZF9pbnRfMiAofjAsIH4wKTsKICBUUkVFX1RZUEUgKHRtYXNrKSA9ICgqbGFuZ19ob29rcy50eXBlcy5zaWduZWRfdHlwZSkgKHR5cGUpOwogIGZvcmNlX2ZpdF90eXBlICh0bWFzaywgMCk7CiAgcmV0dXJuCiAgICB0cmVlX2ludF9jc3RfZXF1YWwgKG1hc2ssCgkJCWNvbnN0X2Jpbm9wIChSU0hJRlRfRVhQUiwKCQkJCSAgICAgY29uc3RfYmlub3AgKExTSElGVF9FWFBSLCB0bWFzaywKCQkJCQkJICBzaXplX2ludCAocHJlY2lzaW9uIC0gc2l6ZSksCgkJCQkJCSAgMCksCgkJCQkgICAgIHNpemVfaW50IChwcmVjaXNpb24gLSBzaXplKSwgMCkpOwp9CgovKiBTdWJyb3V0aW5lIGZvciBmb2xkOiBkZXRlcm1pbmUgaWYgVkFMIGlzIHRoZSBJTlRFR0VSX0NPTlNUIHRoYXQKICAgcmVwcmVzZW50cyB0aGUgc2lnbiBiaXQgb2YgRVhQJ3MgdHlwZS4gIElmIEVYUCByZXByZXNlbnRzIGEgc2lnbgogICBvciB6ZXJvIGV4dGVuc2lvbiwgYWxzbyB0ZXN0IFZBTCBhZ2FpbnN0IHRoZSB1bmV4dGVuZGVkIHR5cGUuCiAgIFRoZSByZXR1cm4gdmFsdWUgaXMgdGhlIChzdWIpZXhwcmVzc2lvbiB3aG9zZSBzaWduIGJpdCBpcyBWQUwsCiAgIG9yIE5VTExfVFJFRSBvdGhlcndpc2UuICAqLwoKc3RhdGljIHRyZWUKc2lnbl9iaXRfcCAodHJlZSBleHAsIHRyZWUgdmFsKQp7CiAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCBtYXNrX2xvLCBsbzsKICBIT1NUX1dJREVfSU5UIG1hc2tfaGksIGhpOwogIGludCB3aWR0aDsKICB0cmVlIHQ7CgogIC8qIFRyZWUgRVhQIG11c3QgaGF2ZSBhbiBpbnRlZ3JhbCB0eXBlLiAgKi8KICB0ID0gVFJFRV9UWVBFIChleHApOwogIGlmICghIElOVEVHUkFMX1RZUEVfUCAodCkpCiAgICByZXR1cm4gTlVMTF9UUkVFOwoKICAvKiBUcmVlIFZBTCBtdXN0IGJlIGFuIGludGVnZXIgY29uc3RhbnQuICAqLwogIGlmIChUUkVFX0NPREUgKHZhbCkgIT0gSU5URUdFUl9DU1QKICAgICAgfHwgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAodmFsKSkKICAgIHJldHVybiBOVUxMX1RSRUU7CgogIHdpZHRoID0gVFlQRV9QUkVDSVNJT04gKHQpOwogIGlmICh3aWR0aCA+IEhPU1RfQklUU19QRVJfV0lERV9JTlQpCiAgICB7CiAgICAgIGhpID0gKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQpIDEgPDwgKHdpZHRoIC0gSE9TVF9CSVRTX1BFUl9XSURFX0lOVCAtIDEpOwogICAgICBsbyA9IDA7CgogICAgICBtYXNrX2hpID0gKCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSAtMQoJCSA+PiAoMiAqIEhPU1RfQklUU19QRVJfV0lERV9JTlQgLSB3aWR0aCkpOwogICAgICBtYXNrX2xvID0gLTE7CiAgICB9CiAgZWxzZQogICAgewogICAgICBoaSA9IDA7CiAgICAgIGxvID0gKHVuc2lnbmVkIEhPU1RfV0lERV9JTlQpIDEgPDwgKHdpZHRoIC0gMSk7CgogICAgICBtYXNrX2hpID0gMDsKICAgICAgbWFza19sbyA9ICgodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgLTEKCQkgPj4gKEhPU1RfQklUU19QRVJfV0lERV9JTlQgLSB3aWR0aCkpOwogICAgfQoKICAvKiBXZSBtYXNrIG9mZiB0aG9zZSBiaXRzIGJleW9uZCBUUkVFX1RZUEUgKGV4cCkgc28gdGhhdCB3ZSBjYW4KICAgICB0cmVhdCBWQUwgYXMgaWYgaXQgd2VyZSB1bnNpZ25lZC4gICovCiAgaWYgKChUUkVFX0lOVF9DU1RfSElHSCAodmFsKSAmIG1hc2tfaGkpID09IGhpCiAgICAgICYmIChUUkVFX0lOVF9DU1RfTE9XICh2YWwpICYgbWFza19sbykgPT0gbG8pCiAgICByZXR1cm4gZXhwOwoKICAvKiBIYW5kbGUgZXh0ZW5zaW9uIGZyb20gYSBuYXJyb3dlciB0eXBlLiAgKi8KICBpZiAoVFJFRV9DT0RFIChleHApID09IE5PUF9FWFBSCiAgICAgICYmIFRZUEVfUFJFQ0lTSU9OIChUUkVFX1RZUEUgKFRSRUVfT1BFUkFORCAoZXhwLCAwKSkpIDwgd2lkdGgpCiAgICByZXR1cm4gc2lnbl9iaXRfcCAoVFJFRV9PUEVSQU5EIChleHAsIDApLCB2YWwpOwoKICByZXR1cm4gTlVMTF9UUkVFOwp9CgovKiBTdWJyb3V0aW5lIGZvciBmb2xkX3RydXRob3A6IGRldGVybWluZSBpZiBhbiBvcGVyYW5kIGlzIHNpbXBsZSBlbm91Z2gKICAgdG8gYmUgZXZhbHVhdGVkIHVuY29uZGl0aW9uYWxseS4gICovCgpzdGF0aWMgaW50CnNpbXBsZV9vcGVyYW5kX3AgKHRyZWUgZXhwKQp7CiAgLyogU3RyaXAgYW55IGNvbnZlcnNpb25zIHRoYXQgZG9uJ3QgY2hhbmdlIHRoZSBtYWNoaW5lIG1vZGUuICAqLwogIHdoaWxlICgoVFJFRV9DT0RFIChleHApID09IE5PUF9FWFBSCgkgIHx8IFRSRUVfQ09ERSAoZXhwKSA9PSBDT05WRVJUX0VYUFIpCgkgJiYgKFRZUEVfTU9ERSAoVFJFRV9UWVBFIChleHApKQoJICAgICA9PSBUWVBFX01PREUgKFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChleHAsIDApKSkpKQogICAgZXhwID0gVFJFRV9PUEVSQU5EIChleHAsIDApOwoKICByZXR1cm4gKFRSRUVfQ09ERV9DTEFTUyAoVFJFRV9DT0RFIChleHApKSA9PSAnYycKCSAgfHwgKERFQ0xfUCAoZXhwKQoJICAgICAgJiYgISBUUkVFX0FERFJFU1NBQkxFIChleHApCgkgICAgICAmJiAhIFRSRUVfVEhJU19WT0xBVElMRSAoZXhwKQoJICAgICAgJiYgISBERUNMX05PTkxPQ0FMIChleHApCgkgICAgICAvKiBEb24ndCByZWdhcmQgZ2xvYmFsIHZhcmlhYmxlcyBhcyBzaW1wbGUuICBUaGV5IG1heSBiZQoJCSBhbGxvY2F0ZWQgaW4gd2F5cyB1bmtub3duIHRvIHRoZSBjb21waWxlciAoc2hhcmVkIG1lbW9yeSwKCQkgI3ByYWdtYSB3ZWFrLCBldGMpLiAgKi8KCSAgICAgICYmICEgVFJFRV9QVUJMSUMgKGV4cCkKCSAgICAgICYmICEgREVDTF9FWFRFUk5BTCAoZXhwKQoJICAgICAgLyogTG9hZGluZyBhIHN0YXRpYyB2YXJpYWJsZSBpcyB1bmR1bHkgZXhwZW5zaXZlLCBidXQgZ2xvYmFsCgkJIHJlZ2lzdGVycyBhcmVuJ3QgZXhwZW5zaXZlLiAgKi8KCSAgICAgICYmICghIFRSRUVfU1RBVElDIChleHApIHx8IERFQ0xfUkVHSVNURVIgKGV4cCkpKSk7Cn0KDAovKiBUaGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBhcmUgc3Vicm91dGluZXMgdG8gZm9sZF9yYW5nZV90ZXN0IGFuZCBhbGxvdyBpdCB0bwogICB0cnkgdG8gY2hhbmdlIGEgbG9naWNhbCBjb21iaW5hdGlvbiBvZiBjb21wYXJpc29ucyBpbnRvIGEgcmFuZ2UgdGVzdC4KCiAgIEZvciBleGFtcGxlLCBib3RoCglYID09IDIgfHwgWCA9PSAzIHx8IFggPT0gNCB8fCBYID09IDUKICAgYW5kCglYID49IDIgJiYgWCA8PSA1CiAgIGFyZSBjb252ZXJ0ZWQgdG8KCSh1bnNpZ25lZCkgKFggLSAyKSA8PSAzCgogICBXZSBkZXNjcmliZSBlYWNoIHNldCBvZiBjb21wYXJpc29ucyBhcyBiZWluZyBlaXRoZXIgaW5zaWRlIG9yIG91dHNpZGUKICAgYSByYW5nZSwgdXNpbmcgYSB2YXJpYWJsZSBuYW1lZCBsaWtlIElOX1AsIGFuZCB0aGVuIGRlc2NyaWJlIHRoZQogICByYW5nZSB3aXRoIGEgbG93ZXIgYW5kIHVwcGVyIGJvdW5kLiAgSWYgb25lIG9mIHRoZSBib3VuZHMgaXMgb21pdHRlZCwKICAgaXQgcmVwcmVzZW50cyBlaXRoZXIgdGhlIGhpZ2hlc3Qgb3IgbG93ZXN0IHZhbHVlIG9mIHRoZSB0eXBlLgoKICAgSW4gdGhlIGNvbW1lbnRzIGJlbG93LCB3ZSByZXByZXNlbnQgYSByYW5nZSBieSB0d28gbnVtYmVycyBpbiBicmFja2V0cwogICBwcmVjZWRlZCBieSBhICIrIiB0byBkZXNpZ25hdGUgYmVpbmcgaW5zaWRlIHRoYXQgcmFuZ2UsIG9yIGEgIi0iIHRvCiAgIGRlc2lnbmF0ZSBiZWluZyBvdXRzaWRlIHRoYXQgcmFuZ2UsIHNvIHRoZSBjb25kaXRpb24gY2FuIGJlIGludmVydGVkIGJ5CiAgIGZsaXBwaW5nIHRoZSBwcmVmaXguICBBbiBvbWl0dGVkIGJvdW5kIGlzIHJlcHJlc2VudGVkIGJ5IGEgIi0iLiAgRm9yCiAgIGV4YW1wbGUsICItIFstLCAxMF0iIG1lYW5zIGJlaW5nIG91dHNpZGUgdGhlIHJhbmdlIHN0YXJ0aW5nIGF0IHRoZSBsb3dlc3QKICAgcG9zc2libGUgdmFsdWUgYW5kIGVuZGluZyBhdCAxMCwgaW4gb3RoZXIgd29yZHMsIGJlaW5nIGdyZWF0ZXIgdGhhbiAxMC4KICAgVGhlIHJhbmdlICIrIFstLCAtXSIgaXMgYWx3YXlzIHRydWUgYW5kIGhlbmNlIHRoZSByYW5nZSAiLSBbLSwgLV0iIGlzCiAgIGFsd2F5cyBmYWxzZS4KCiAgIFdlIHNldCB1cCB0aGluZ3Mgc28gdGhhdCB0aGUgbWlzc2luZyBib3VuZHMgYXJlIGhhbmRsZWQgaW4gYSBjb25zaXN0ZW50CiAgIG1hbm5lciBzbyBuZWl0aGVyIGEgbWlzc2luZyBib3VuZCBub3IgInRydWUiIGFuZCAiZmFsc2UiIG5lZWQgdG8gYmUKICAgaGFuZGxlZCB1c2luZyBhIHNwZWNpYWwgY2FzZS4gICovCgovKiBSZXR1cm4gdGhlIHJlc3VsdCBvZiBhcHBseWluZyBDT0RFIHRvIEFSRzAgYW5kIEFSRzEsIGJ1dCBoYW5kbGUgdGhlIGNhc2UKICAgb2YgQVJHMCBhbmQvb3IgQVJHMSBiZWluZyBvbWl0dGVkLCBtZWFuaW5nIGFuIHVubGltaXRlZCByYW5nZS4gVVBQRVIwX1AKICAgYW5kIFVQUEVSMV9QIGFyZSBub256ZXJvIGlmIHRoZSByZXNwZWN0aXZlIGFyZ3VtZW50IGlzIGFuIHVwcGVyIGJvdW5kCiAgIGFuZCB6ZXJvIGZvciBhIGxvd2VyLiAgVFlQRSwgaWYgbm9uemVybywgaXMgdGhlIHR5cGUgb2YgdGhlIHJlc3VsdDsgaXQKICAgbXVzdCBiZSBzcGVjaWZpZWQgZm9yIGEgY29tcGFyaXNvbi4gIEFSRzEgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gQVJHMCdzCiAgIHR5cGUgaWYgYm90aCBhcmUgc3BlY2lmaWVkLiAgKi8KCnN0YXRpYyB0cmVlCnJhbmdlX2Jpbm9wIChlbnVtIHRyZWVfY29kZSBjb2RlLCB0cmVlIHR5cGUsIHRyZWUgYXJnMCwgaW50IHVwcGVyMF9wLAoJICAgICB0cmVlIGFyZzEsIGludCB1cHBlcjFfcCkKewogIHRyZWUgdGVtOwogIGludCByZXN1bHQ7CiAgaW50IHNnbjAsIHNnbjE7CgogIC8qIElmIG5laXRoZXIgYXJnIHJlcHJlc2VudHMgaW5maW5pdHksIGRvIHRoZSBub3JtYWwgb3BlcmF0aW9uLgogICAgIEVsc2UsIGlmIG5vdCBhIGNvbXBhcmlzb24sIHJldHVybiBpbmZpbml0eS4gIEVsc2UgaGFuZGxlIHRoZSBzcGVjaWFsCiAgICAgY29tcGFyaXNvbiBydWxlcy4gTm90ZSB0aGF0IG1vc3Qgb2YgdGhlIGNhc2VzIGJlbG93IHdvbid0IG9jY3VyLCBidXQKICAgICBhcmUgaGFuZGxlZCBmb3IgY29uc2lzdGVuY3kuICAqLwoKICBpZiAoYXJnMCAhPSAwICYmIGFyZzEgIT0gMCkKICAgIHsKICAgICAgdGVtID0gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUgIT0gMCA/IHR5cGUgOiBUUkVFX1RZUEUgKGFyZzApLAoJCQkgYXJnMCwgZm9sZF9jb252ZXJ0IChUUkVFX1RZUEUgKGFyZzApLCBhcmcxKSkpOwogICAgICBTVFJJUF9OT1BTICh0ZW0pOwogICAgICByZXR1cm4gVFJFRV9DT0RFICh0ZW0pID09IElOVEVHRVJfQ1NUID8gdGVtIDogMDsKICAgIH0KCiAgaWYgKFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgIT0gJzwnKQogICAgcmV0dXJuIDA7CgogIC8qIFNldCBTR05bMDFdIHRvIC0xIGlmIEFSR1swMV0gaXMgYSBsb3dlciBib3VuZCwgMSBmb3IgdXBwZXIsIGFuZCAwCiAgICAgZm9yIG5laXRoZXIuICBJbiByZWFsIG1hdGhzLCB3ZSBjYW5ub3QgYXNzdW1lIG9wZW4gZW5kZWQgcmFuZ2VzIGFyZQogICAgIHRoZSBzYW1lLiBCdXQsIHRoaXMgaXMgY29tcHV0ZXIgYXJpdGhtZXRpYywgd2hlcmUgbnVtYmVycyBhcmUgZmluaXRlLgogICAgIFdlIGNhbiB0aGVyZWZvcmUgbWFrZSB0aGUgdHJhbnNmb3JtYXRpb24gb2YgYW55IHVuYm91bmRlZCByYW5nZSB3aXRoCiAgICAgdGhlIHZhbHVlIFosIFogYmVpbmcgZ3JlYXRlciB0aGFuIGFueSByZXByZXNlbnRhYmxlIG51bWJlci4gVGhpcyBwZXJtaXRzCiAgICAgdXMgdG8gdHJlYXQgdW5ib3VuZGVkIHJhbmdlcyBhcyBlcXVhbC4gICovCiAgc2duMCA9IGFyZzAgIT0gMCA/IDAgOiAodXBwZXIwX3AgPyAxIDogLTEpOwogIHNnbjEgPSBhcmcxICE9IDAgPyAwIDogKHVwcGVyMV9wID8gMSA6IC0xKTsKICBzd2l0Y2ggKGNvZGUpCiAgICB7CiAgICBjYXNlIEVRX0VYUFI6CiAgICAgIHJlc3VsdCA9IHNnbjAgPT0gc2duMTsKICAgICAgYnJlYWs7CiAgICBjYXNlIE5FX0VYUFI6CiAgICAgIHJlc3VsdCA9IHNnbjAgIT0gc2duMTsKICAgICAgYnJlYWs7CiAgICBjYXNlIExUX0VYUFI6CiAgICAgIHJlc3VsdCA9IHNnbjAgPCBzZ24xOwogICAgICBicmVhazsKICAgIGNhc2UgTEVfRVhQUjoKICAgICAgcmVzdWx0ID0gc2duMCA8PSBzZ24xOwogICAgICBicmVhazsKICAgIGNhc2UgR1RfRVhQUjoKICAgICAgcmVzdWx0ID0gc2duMCA+IHNnbjE7CiAgICAgIGJyZWFrOwogICAgY2FzZSBHRV9FWFBSOgogICAgICByZXN1bHQgPSBzZ24wID49IHNnbjE7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgYWJvcnQgKCk7CiAgICB9CgogIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIHJlc3VsdCA/IGludGVnZXJfb25lX25vZGUgOiBpbnRlZ2VyX3plcm9fbm9kZSk7Cn0KDAovKiBHaXZlbiBFWFAsIGEgbG9naWNhbCBleHByZXNzaW9uLCBzZXQgdGhlIHJhbmdlIGl0IGlzIHRlc3RpbmcgaW50bwogICB2YXJpYWJsZXMgZGVub3RlZCBieSBQSU5fUCwgUExPVywgYW5kIFBISUdILiAgUmV0dXJuIHRoZSBleHByZXNzaW9uCiAgIGFjdHVhbGx5IGJlaW5nIHRlc3RlZC4gICpQTE9XIGFuZCAqUEhJR0ggd2lsbCBiZSBtYWRlIG9mIHRoZSBzYW1lIHR5cGUKICAgYXMgdGhlIHJldHVybmVkIGV4cHJlc3Npb24uICBJZiBFWFAgaXMgbm90IGEgY29tcGFyaXNvbiwgd2Ugd2lsbCBtb3N0CiAgIGxpa2VseSBub3QgYmUgcmV0dXJuaW5nIGEgdXNlZnVsIHZhbHVlIGFuZCByYW5nZS4gICovCgpzdGF0aWMgdHJlZQptYWtlX3JhbmdlICh0cmVlIGV4cCwgaW50ICpwaW5fcCwgdHJlZSAqcGxvdywgdHJlZSAqcGhpZ2gpCnsKICBlbnVtIHRyZWVfY29kZSBjb2RlOwogIHRyZWUgYXJnMCA9IE5VTExfVFJFRSwgYXJnMSA9IE5VTExfVFJFRSwgdHlwZSA9IE5VTExfVFJFRTsKICB0cmVlIG9yaWdfdHlwZSA9IE5VTExfVFJFRTsKICBpbnQgaW5fcCwgbl9pbl9wOwogIHRyZWUgbG93LCBoaWdoLCBuX2xvdywgbl9oaWdoOwoKICAvKiBTdGFydCB3aXRoIHNpbXBseSBzYXlpbmcgIkVYUCAhPSAwIiBhbmQgdGhlbiBsb29rIGF0IHRoZSBjb2RlIG9mIEVYUAogICAgIGFuZCBzZWUgaWYgd2UgY2FuIHJlZmluZSB0aGUgcmFuZ2UuICBTb21lIG9mIHRoZSBjYXNlcyBiZWxvdyBtYXkgbm90CiAgICAgaGFwcGVuLCBidXQgaXQgZG9lc24ndCBzZWVtIHdvcnRoIHdvcnJ5aW5nIGFib3V0IHRoaXMuICBXZSAiY29udGludWUiCiAgICAgdGhlIG91dGVyIGxvb3Agd2hlbiB3ZSd2ZSBjaGFuZ2VkIHNvbWV0aGluZzsgb3RoZXJ3aXNlIHdlICJicmVhayIKICAgICB0aGUgc3dpdGNoLCB3aGljaCB3aWxsICJicmVhayIgdGhlIHdoaWxlLiAgKi8KCiAgaW5fcCA9IDA7CiAgbG93ID0gaGlnaCA9IGZvbGRfY29udmVydCAoVFJFRV9UWVBFIChleHApLCBpbnRlZ2VyX3plcm9fbm9kZSk7CgogIHdoaWxlICgxKQogICAgewogICAgICBjb2RlID0gVFJFRV9DT0RFIChleHApOwoKICAgICAgaWYgKElTX0VYUFJfQ09ERV9DTEFTUyAoVFJFRV9DT0RFX0NMQVNTIChjb2RlKSkpCgl7CgkgIGlmIChmaXJzdF9ydGxfb3AgKGNvZGUpID4gMCkKCSAgICBhcmcwID0gVFJFRV9PUEVSQU5EIChleHAsIDApOwoJICBpZiAoVFJFRV9DT0RFX0NMQVNTIChjb2RlKSA9PSAnPCcKCSAgICAgIHx8IFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgPT0gJzEnCgkgICAgICB8fCBUUkVFX0NPREVfQ0xBU1MgKGNvZGUpID09ICcyJykKCSAgICB0eXBlID0gVFJFRV9UWVBFIChhcmcwKTsKCSAgaWYgKFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgPT0gJzInCgkgICAgICB8fCBUUkVFX0NPREVfQ0xBU1MgKGNvZGUpID09ICc8JwoJICAgICAgfHwgKFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgPT0gJ2UnCgkJICAmJiBUUkVFX0NPREVfTEVOR1RIIChjb2RlKSA+IDEpKQoJICAgIGFyZzEgPSBUUkVFX09QRVJBTkQgKGV4cCwgMSk7Cgl9CgogICAgICAvKiBTZXQgT1JJR19UWVBFIGFzIHNvb24gYXMgVFlQRSBpcyBub24tbnVsbCBzbyB0aGF0IHdlIGRvIG5vdAoJIGxvc2UgYSBjYXN0IGJ5IGFjY2lkZW50LiAgKi8KICAgICAgaWYgKHR5cGUgIT0gTlVMTF9UUkVFICYmIG9yaWdfdHlwZSA9PSBOVUxMX1RSRUUpCglvcmlnX3R5cGUgPSB0eXBlOwoKICAgICAgc3dpdGNoIChjb2RlKQoJewoJY2FzZSBUUlVUSF9OT1RfRVhQUjoKCSAgaW5fcCA9ICEgaW5fcCwgZXhwID0gYXJnMDsKCSAgY29udGludWU7CgoJY2FzZSBFUV9FWFBSOiBjYXNlIE5FX0VYUFI6CgljYXNlIExUX0VYUFI6IGNhc2UgTEVfRVhQUjogY2FzZSBHRV9FWFBSOiBjYXNlIEdUX0VYUFI6CgkgIC8qIFdlIGNhbiBvbmx5IGRvIHNvbWV0aGluZyBpZiB0aGUgcmFuZ2UgaXMgdGVzdGluZyBmb3IgemVybwoJICAgICBhbmQgaWYgdGhlIHNlY29uZCBvcGVyYW5kIGlzIGFuIGludGVnZXIgY29uc3RhbnQuICBOb3RlIHRoYXQKCSAgICAgc2F5aW5nIHNvbWV0aGluZyBpcyAiaW4iIHRoZSByYW5nZSB3ZSBtYWtlIGlzIGRvbmUgYnkKCSAgICAgY29tcGxlbWVudGluZyBJTl9QIHNpbmNlIGl0IHdpbGwgc2V0IGluIHRoZSBpbml0aWFsIGNhc2Ugb2YKCSAgICAgYmVpbmcgbm90IGVxdWFsIHRvIHplcm87ICJvdXQiIGlzIGxlYXZpbmcgaXQgYWxvbmUuICAqLwoJICBpZiAobG93ID09IDAgfHwgaGlnaCA9PSAwCgkgICAgICB8fCAhIGludGVnZXJfemVyb3AgKGxvdykgfHwgISBpbnRlZ2VyX3plcm9wIChoaWdoKQoJICAgICAgfHwgVFJFRV9DT0RFIChhcmcxKSAhPSBJTlRFR0VSX0NTVCkKCSAgICBicmVhazsKCgkgIHN3aXRjaCAoY29kZSkKCSAgICB7CgkgICAgY2FzZSBORV9FWFBSOiAgLyogLSBbYywgY10gICovCgkgICAgICBsb3cgPSBoaWdoID0gYXJnMTsKCSAgICAgIGJyZWFrOwoJICAgIGNhc2UgRVFfRVhQUjogIC8qICsgW2MsIGNdICAqLwoJICAgICAgaW5fcCA9ICEgaW5fcCwgbG93ID0gaGlnaCA9IGFyZzE7CgkgICAgICBicmVhazsKCSAgICBjYXNlIEdUX0VYUFI6ICAvKiAtIFstLCBjXSAqLwoJICAgICAgbG93ID0gMCwgaGlnaCA9IGFyZzE7CgkgICAgICBicmVhazsKCSAgICBjYXNlIEdFX0VYUFI6ICAvKiArIFtjLCAtXSAqLwoJICAgICAgaW5fcCA9ICEgaW5fcCwgbG93ID0gYXJnMSwgaGlnaCA9IDA7CgkgICAgICBicmVhazsKCSAgICBjYXNlIExUX0VYUFI6ICAvKiAtIFtjLCAtXSAqLwoJICAgICAgbG93ID0gYXJnMSwgaGlnaCA9IDA7CgkgICAgICBicmVhazsKCSAgICBjYXNlIExFX0VYUFI6ICAvKiArIFstLCBjXSAqLwoJICAgICAgaW5fcCA9ICEgaW5fcCwgbG93ID0gMCwgaGlnaCA9IGFyZzE7CgkgICAgICBicmVhazsKCSAgICBkZWZhdWx0OgoJICAgICAgYWJvcnQgKCk7CgkgICAgfQoKCSAgZXhwID0gYXJnMDsKCgkgIC8qIElmIHRoaXMgaXMgYW4gdW5zaWduZWQgY29tcGFyaXNvbiwgd2UgYWxzbyBrbm93IHRoYXQgRVhQIGlzCgkgICAgIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB6ZXJvLiAgV2UgYmFzZSB0aGUgcmFuZ2UgdGVzdHMgd2UgbWFrZQoJICAgICBvbiB0aGF0IGZhY3QsIHNvIHdlIHJlY29yZCBpdCBoZXJlIHNvIHdlIGNhbiBwYXJzZSBleGlzdGluZwoJICAgICByYW5nZSB0ZXN0cy4gICovCgkgIGlmIChUUkVFX1VOU0lHTkVEICh0eXBlKSAmJiAobG93ID09IDAgfHwgaGlnaCA9PSAwKSkKCSAgICB7CgkgICAgICBpZiAoISBtZXJnZV9yYW5nZXMgKCZuX2luX3AsICZuX2xvdywgJm5faGlnaCwgaW5fcCwgbG93LCBoaWdoLAoJCQkJICAxLCBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfemVyb19ub2RlKSwKCQkJCSAgTlVMTF9UUkVFKSkKCQlicmVhazsKCgkgICAgICBpbl9wID0gbl9pbl9wLCBsb3cgPSBuX2xvdywgaGlnaCA9IG5faGlnaDsKCgkgICAgICAvKiBJZiB0aGUgaGlnaCBib3VuZCBpcyBtaXNzaW5nLCBidXQgd2UgaGF2ZSBhIG5vbnplcm8gbG93CgkJIGJvdW5kLCByZXZlcnNlIHRoZSByYW5nZSBzbyBpdCBnb2VzIGZyb20gemVybyB0byB0aGUgbG93IGJvdW5kCgkJIG1pbnVzIDEuICAqLwoJICAgICAgaWYgKGhpZ2ggPT0gMCAmJiBsb3cgJiYgISBpbnRlZ2VyX3plcm9wIChsb3cpKQoJCXsKCQkgIGluX3AgPSAhIGluX3A7CgkJICBoaWdoID0gcmFuZ2VfYmlub3AgKE1JTlVTX0VYUFIsIE5VTExfVFJFRSwgbG93LCAwLAoJCQkJICAgICAgaW50ZWdlcl9vbmVfbm9kZSwgMCk7CgkJICBsb3cgPSBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfemVyb19ub2RlKTsKCQl9CgkgICAgfQoJICBjb250aW51ZTsKCgljYXNlIE5FR0FURV9FWFBSOgoJICAvKiAoLXgpIElOIFthLGJdIC0+IHggaW4gWy1iLCAtYV0gICovCgkgIG5fbG93ID0gcmFuZ2VfYmlub3AgKE1JTlVTX0VYUFIsIHR5cGUsCgkJCSAgICAgICBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfemVyb19ub2RlKSwKCQkJICAgICAgIDAsIGhpZ2gsIDEpOwoJICBuX2hpZ2ggPSByYW5nZV9iaW5vcCAoTUlOVVNfRVhQUiwgdHlwZSwKCQkJCWZvbGRfY29udmVydCAodHlwZSwgaW50ZWdlcl96ZXJvX25vZGUpLAoJCQkJMCwgbG93LCAwKTsKCSAgbG93ID0gbl9sb3csIGhpZ2ggPSBuX2hpZ2g7CgkgIGV4cCA9IGFyZzA7CgkgIGNvbnRpbnVlOwoKCWNhc2UgQklUX05PVF9FWFBSOgoJICAvKiB+IFggLT4gLVggLSAxICAqLwoJICBleHAgPSBidWlsZCAoTUlOVVNfRVhQUiwgdHlwZSwgbmVnYXRlX2V4cHIgKGFyZzApLAoJCSAgICAgICBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfb25lX25vZGUpKTsKCSAgY29udGludWU7CgoJY2FzZSBQTFVTX0VYUFI6ICBjYXNlIE1JTlVTX0VYUFI6CgkgIGlmIChUUkVFX0NPREUgKGFyZzEpICE9IElOVEVHRVJfQ1NUKQoJICAgIGJyZWFrOwoKCSAgLyogSWYgRVhQIGlzIHNpZ25lZCwgYW55IG92ZXJmbG93IGluIHRoZSBjb21wdXRhdGlvbiBpcyB1bmRlZmluZWQsCgkgICAgIHNvIHdlIGRvbid0IHdvcnJ5IGFib3V0IGl0IHNvIGxvbmcgYXMgb3VyIGNvbXB1dGF0aW9ucyBvbgoJICAgICB0aGUgYm91bmRzIGRvbid0IG92ZXJmbG93LiAgRm9yIHVuc2lnbmVkLCBvdmVyZmxvdyBpcyBkZWZpbmVkCgkgICAgIGFuZCB0aGlzIGlzIGV4YWN0bHkgdGhlIHJpZ2h0IHRoaW5nLiAgKi8KCSAgbl9sb3cgPSByYW5nZV9iaW5vcCAoY29kZSA9PSBNSU5VU19FWFBSID8gUExVU19FWFBSIDogTUlOVVNfRVhQUiwKCQkJICAgICAgIHR5cGUsIGxvdywgMCwgYXJnMSwgMCk7CgkgIG5faGlnaCA9IHJhbmdlX2Jpbm9wIChjb2RlID09IE1JTlVTX0VYUFIgPyBQTFVTX0VYUFIgOiBNSU5VU19FWFBSLAoJCQkJdHlwZSwgaGlnaCwgMSwgYXJnMSwgMCk7CgkgIGlmICgobl9sb3cgIT0gMCAmJiBUUkVFX09WRVJGTE9XIChuX2xvdykpCgkgICAgICB8fCAobl9oaWdoICE9IDAgJiYgVFJFRV9PVkVSRkxPVyAobl9oaWdoKSkpCgkgICAgYnJlYWs7CgoJICAvKiBDaGVjayBmb3IgYW4gdW5zaWduZWQgcmFuZ2Ugd2hpY2ggaGFzIHdyYXBwZWQgYXJvdW5kIHRoZSBtYXhpbXVtCgkgICAgIHZhbHVlIHRodXMgbWFraW5nIG5faGlnaCA8IG5fbG93LCBhbmQgbm9ybWFsaXplIGl0LiAgKi8KCSAgaWYgKG5fbG93ICYmIG5faGlnaCAmJiB0cmVlX2ludF9jc3RfbHQgKG5faGlnaCwgbl9sb3cpKQoJICAgIHsKCSAgICAgIGxvdyA9IHJhbmdlX2Jpbm9wIChQTFVTX0VYUFIsIHR5cGUsIG5faGlnaCwgMCwKCQkJCSBpbnRlZ2VyX29uZV9ub2RlLCAwKTsKCSAgICAgIGhpZ2ggPSByYW5nZV9iaW5vcCAoTUlOVVNfRVhQUiwgdHlwZSwgbl9sb3csIDAsCgkJCQkgIGludGVnZXJfb25lX25vZGUsIDApOwoKCSAgICAgIC8qIElmIHRoZSByYW5nZSBpcyBvZiB0aGUgZm9ybSArLy0gWyB4KzEsIHggXSwgd2Ugd29uJ3QKCQkgYmUgYWJsZSB0byBub3JtYWxpemUgaXQuICBCdXQgdGhlbiwgaXQgcmVwcmVzZW50cyB0aGUKCQkgd2hvbGUgcmFuZ2Ugb3IgdGhlIGVtcHR5IHNldCwgc28gbWFrZSBpdAoJCSArLy0gWyAtLCAtIF0uICAqLwoJICAgICAgaWYgKHRyZWVfaW50X2NzdF9lcXVhbCAobl9sb3csIGxvdykKCQkgICYmIHRyZWVfaW50X2NzdF9lcXVhbCAobl9oaWdoLCBoaWdoKSkKCQlsb3cgPSBoaWdoID0gMDsKCSAgICAgIGVsc2UKCQlpbl9wID0gISBpbl9wOwoJICAgIH0KCSAgZWxzZQoJICAgIGxvdyA9IG5fbG93LCBoaWdoID0gbl9oaWdoOwoKCSAgZXhwID0gYXJnMDsKCSAgY29udGludWU7CgoJY2FzZSBOT1BfRVhQUjogIGNhc2UgTk9OX0xWQUxVRV9FWFBSOiAgY2FzZSBDT05WRVJUX0VYUFI6CgkgIGlmIChUWVBFX1BSRUNJU0lPTiAodHlwZSkgPiBUWVBFX1BSRUNJU0lPTiAob3JpZ190eXBlKSkKCSAgICBicmVhazsKCgkgIGlmICghIElOVEVHUkFMX1RZUEVfUCAodHlwZSkKCSAgICAgIHx8IChsb3cgIT0gMCAmJiAhIGludF9maXRzX3R5cGVfcCAobG93LCB0eXBlKSkKCSAgICAgIHx8IChoaWdoICE9IDAgJiYgISBpbnRfZml0c190eXBlX3AgKGhpZ2gsIHR5cGUpKSkKCSAgICBicmVhazsKCgkgIG5fbG93ID0gbG93LCBuX2hpZ2ggPSBoaWdoOwoKCSAgaWYgKG5fbG93ICE9IDApCgkgICAgbl9sb3cgPSBmb2xkX2NvbnZlcnQgKHR5cGUsIG5fbG93KTsKCgkgIGlmIChuX2hpZ2ggIT0gMCkKCSAgICBuX2hpZ2ggPSBmb2xkX2NvbnZlcnQgKHR5cGUsIG5faGlnaCk7CgoJICAvKiBJZiB3ZSdyZSBjb252ZXJ0aW5nIGZyb20gYW4gdW5zaWduZWQgdG8gYSBzaWduZWQgdHlwZSwKCSAgICAgd2Ugd2lsbCBiZSBkb2luZyB0aGUgY29tcGFyaXNvbiBhcyB1bnNpZ25lZC4gIFRoZSB0ZXN0cyBhYm92ZQoJICAgICBoYXZlIGFscmVhZHkgdmVyaWZpZWQgdGhhdCBMT1cgYW5kIEhJR0ggYXJlIGJvdGggcG9zaXRpdmUuCgoJICAgICBTbyB3ZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBvcmlnaW5hbCB1bnNpZ25lZCB2YWx1ZSB3aWxsCgkgICAgIGJlIGludGVycHJldGVkIGFzIHBvc2l0aXZlLiAgKi8KCSAgaWYgKFRSRUVfVU5TSUdORUQgKHR5cGUpICYmICEgVFJFRV9VTlNJR05FRCAoVFJFRV9UWVBFIChleHApKSkKCSAgICB7CgkgICAgICB0cmVlIGVxdWl2X3R5cGUgPSAoKmxhbmdfaG9va3MudHlwZXMudHlwZV9mb3JfbW9kZSkKCQkoVFlQRV9NT0RFICh0eXBlKSwgMSk7CgkgICAgICB0cmVlIGhpZ2hfcG9zaXRpdmU7CgoJICAgICAgLyogQSByYW5nZSB3aXRob3V0IGFuIHVwcGVyIGJvdW5kIGlzLCBuYXR1cmFsbHksIHVuYm91bmRlZC4KCQkgU2luY2UgY29udmVydCB3b3VsZCBoYXZlIGNyb3BwZWQgYSB2ZXJ5IGxhcmdlIHZhbHVlLCB1c2UKCQkgdGhlIG1heCB2YWx1ZSBmb3IgdGhlIGRlc3RpbmF0aW9uIHR5cGUuICAqLwoJICAgICAgaGlnaF9wb3NpdGl2ZQoJCT0gVFlQRV9NQVhfVkFMVUUgKGVxdWl2X3R5cGUpID8gVFlQRV9NQVhfVkFMVUUgKGVxdWl2X3R5cGUpCgkJICA6IFRZUEVfTUFYX1ZBTFVFICh0eXBlKTsKCgkgICAgICBpZiAoVFlQRV9QUkVDSVNJT04gKHR5cGUpID09IFRZUEVfUFJFQ0lTSU9OIChUUkVFX1RZUEUgKGV4cCkpKQoJICAgICAgICBoaWdoX3Bvc2l0aXZlID0gZm9sZCAoYnVpbGQgKFJTSElGVF9FWFBSLCB0eXBlLAoJCQkJCSAgICAgZm9sZF9jb252ZXJ0ICh0eXBlLAoJCQkJCQkJICAgaGlnaF9wb3NpdGl2ZSksCgkJCQkJICAgICBmb2xkX2NvbnZlcnQgKHR5cGUsCgkJCQkJCQkgICBpbnRlZ2VyX29uZV9ub2RlKSkpOwoKCSAgICAgIC8qIElmIHRoZSBsb3cgYm91bmQgaXMgc3BlY2lmaWVkLCAiYW5kIiB0aGUgcmFuZ2Ugd2l0aCB0aGUKCQkgcmFuZ2UgZm9yIHdoaWNoIHRoZSBvcmlnaW5hbCB1bnNpZ25lZCB2YWx1ZSB3aWxsIGJlCgkJIHBvc2l0aXZlLiAgKi8KCSAgICAgIGlmIChsb3cgIT0gMCkKCQl7CgkJICBpZiAoISBtZXJnZV9yYW5nZXMgKCZuX2luX3AsICZuX2xvdywgJm5faGlnaCwKCQkJCSAgICAgIDEsIG5fbG93LCBuX2hpZ2gsIDEsCgkJCQkgICAgICBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfemVyb19ub2RlKSwKCQkJCSAgICAgIGhpZ2hfcG9zaXRpdmUpKQoJCSAgICBicmVhazsKCgkJICBpbl9wID0gKG5faW5fcCA9PSBpbl9wKTsKCQl9CgkgICAgICBlbHNlCgkJewoJCSAgLyogT3RoZXJ3aXNlLCAib3IiIHRoZSByYW5nZSB3aXRoIHRoZSByYW5nZSBvZiB0aGUgaW5wdXQKCQkgICAgIHRoYXQgd2lsbCBiZSBpbnRlcnByZXRlZCBhcyBuZWdhdGl2ZS4gICovCgkJICBpZiAoISBtZXJnZV9yYW5nZXMgKCZuX2luX3AsICZuX2xvdywgJm5faGlnaCwKCQkJCSAgICAgIDAsIG5fbG93LCBuX2hpZ2gsIDEsCgkJCQkgICAgICBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfemVyb19ub2RlKSwKCQkJCSAgICAgIGhpZ2hfcG9zaXRpdmUpKQoJCSAgICBicmVhazsKCgkJICBpbl9wID0gKGluX3AgIT0gbl9pbl9wKTsKCQl9CgkgICAgfQoKCSAgZXhwID0gYXJnMDsKCSAgbG93ID0gbl9sb3csIGhpZ2ggPSBuX2hpZ2g7CgkgIGNvbnRpbnVlOwoKCWRlZmF1bHQ6CgkgIGJyZWFrOwoJfQoKICAgICAgYnJlYWs7CiAgICB9CgogIC8qIElmIEVYUCBpcyBhIGNvbnN0YW50LCB3ZSBjYW4gZXZhbHVhdGUgd2hldGhlciB0aGlzIGlzIHRydWUgb3IgZmFsc2UuICAqLwogIGlmIChUUkVFX0NPREUgKGV4cCkgPT0gSU5URUdFUl9DU1QpCiAgICB7CiAgICAgIGluX3AgPSBpbl9wID09IChpbnRlZ2VyX29uZXAgKHJhbmdlX2Jpbm9wIChHRV9FWFBSLCBpbnRlZ2VyX3R5cGVfbm9kZSwKCQkJCQkJIGV4cCwgMCwgbG93LCAwKSkKCQkgICAgICAmJiBpbnRlZ2VyX29uZXAgKHJhbmdlX2Jpbm9wIChMRV9FWFBSLCBpbnRlZ2VyX3R5cGVfbm9kZSwKCQkJCQkJICAgIGV4cCwgMSwgaGlnaCwgMSkpKTsKICAgICAgbG93ID0gaGlnaCA9IDA7CiAgICAgIGV4cCA9IDA7CiAgICB9CgogICpwaW5fcCA9IGluX3AsICpwbG93ID0gbG93LCAqcGhpZ2ggPSBoaWdoOwogIHJldHVybiBleHA7Cn0KDAovKiBHaXZlbiBhIHJhbmdlLCBMT1csIEhJR0gsIGFuZCBJTl9QLCBhbiBleHByZXNzaW9uLCBFWFAsIGFuZCBhIHJlc3VsdAogICB0eXBlLCBUWVBFLCByZXR1cm4gYW4gZXhwcmVzc2lvbiB0byB0ZXN0IGlmIEVYUCBpcyBpbiAob3Igb3V0IG9mLCBkZXBlbmRpbmcKICAgb24gSU5fUCkgdGhlIHJhbmdlLiAgKi8KCnN0YXRpYyB0cmVlCmJ1aWxkX3JhbmdlX2NoZWNrICh0cmVlIHR5cGUsIHRyZWUgZXhwLCBpbnQgaW5fcCwgdHJlZSBsb3csIHRyZWUgaGlnaCkKewogIHRyZWUgZXR5cGUgPSBUUkVFX1RZUEUgKGV4cCk7CiAgdHJlZSB2YWx1ZTsKCiAgaWYgKCEgaW5fcAogICAgICAmJiAoMCAhPSAodmFsdWUgPSBidWlsZF9yYW5nZV9jaGVjayAodHlwZSwgZXhwLCAxLCBsb3csIGhpZ2gpKSkpCiAgICByZXR1cm4gaW52ZXJ0X3RydXRodmFsdWUgKHZhbHVlKTsKCiAgaWYgKGxvdyA9PSAwICYmIGhpZ2ggPT0gMCkKICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfb25lX25vZGUpOwoKICBpZiAobG93ID09IDApCiAgICByZXR1cm4gZm9sZCAoYnVpbGQgKExFX0VYUFIsIHR5cGUsIGV4cCwgaGlnaCkpOwoKICBpZiAoaGlnaCA9PSAwKQogICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChHRV9FWFBSLCB0eXBlLCBleHAsIGxvdykpOwoKICBpZiAob3BlcmFuZF9lcXVhbF9wIChsb3csIGhpZ2gsIDApKQogICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChFUV9FWFBSLCB0eXBlLCBleHAsIGxvdykpOwoKICBpZiAoaW50ZWdlcl96ZXJvcCAobG93KSkKICAgIHsKICAgICAgaWYgKCEgVFJFRV9VTlNJR05FRCAoZXR5cGUpKQoJewoJICBldHlwZSA9ICgqbGFuZ19ob29rcy50eXBlcy51bnNpZ25lZF90eXBlKSAoZXR5cGUpOwoJICBoaWdoID0gZm9sZF9jb252ZXJ0IChldHlwZSwgaGlnaCk7CgkgIGV4cCA9IGZvbGRfY29udmVydCAoZXR5cGUsIGV4cCk7Cgl9CiAgICAgIHJldHVybiBidWlsZF9yYW5nZV9jaGVjayAodHlwZSwgZXhwLCAxLCAwLCBoaWdoKTsKICAgIH0KCiAgLyogT3B0aW1pemUgKGM+PTEpICYmIChjPD0xMjcpIGludG8gKHNpZ25lZCBjaGFyKWMgPiAwLiAgKi8KICBpZiAoaW50ZWdlcl9vbmVwIChsb3cpICYmIFRSRUVfQ09ERSAoaGlnaCkgPT0gSU5URUdFUl9DU1QpCiAgICB7CiAgICAgIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgbG87CiAgICAgIEhPU1RfV0lERV9JTlQgaGk7CiAgICAgIGludCBwcmVjOwoKICAgICAgLyogRm9yIGVudW1zIHRoZSBjb21wYXJpc29uIHdpbGwgYmUgZG9uZSBpbiB0aGUgdW5kZXJseWluZyB0eXBlLAoJIHNvIHVzaW5nIGVudW0ncyBwcmVjaXNpb24gaXMgd3JvbmcgaGVyZS4KCSBDb25zaWRlciBlLmcuIGVudW0geyBBLCBCLCBDLCBELCBFIH0sIGxvdyA9PSBCIGFuZCBoaWdoID09IEQuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChldHlwZSkgPT0gRU5VTUVSQUxfVFlQRSkKCXByZWMgPSBHRVRfTU9ERV9CSVRTSVpFIChUWVBFX01PREUgKGV0eXBlKSk7CiAgICAgIGVsc2UKCXByZWMgPSBUWVBFX1BSRUNJU0lPTiAoZXR5cGUpOwogICAgICBpZiAocHJlYyA8PSBIT1NUX0JJVFNfUEVSX1dJREVfSU5UKQoJewoJICBoaSA9IDA7CgkgIGxvID0gKCh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSAxIDw8IChwcmVjIC0gMSkpIC0gMTsKCX0KICAgICAgZWxzZQoJewoJICBoaSA9ICgoSE9TVF9XSURFX0lOVCkgMSA8PCAocHJlYyAtIEhPU1RfQklUU19QRVJfV0lERV9JTlQgLSAxKSkgLSAxOwoJICBsbyA9ICh1bnNpZ25lZCBIT1NUX1dJREVfSU5UKSAtMTsKCX0KCiAgICAgIGlmIChUUkVFX0lOVF9DU1RfSElHSCAoaGlnaCkgPT0gaGkgJiYgVFJFRV9JTlRfQ1NUX0xPVyAoaGlnaCkgPT0gbG8pCgl7CgkgIGlmIChUUkVFX1VOU0lHTkVEIChldHlwZSkpCgkgICAgewoJICAgICAgZXR5cGUgPSAoKmxhbmdfaG9va3MudHlwZXMuc2lnbmVkX3R5cGUpIChldHlwZSk7CgkgICAgICBleHAgPSBmb2xkX2NvbnZlcnQgKGV0eXBlLCBleHApOwoJICAgIH0KCSAgcmV0dXJuIGZvbGQgKGJ1aWxkIChHVF9FWFBSLCB0eXBlLCBleHAsCgkJCSAgICAgIGZvbGRfY29udmVydCAoZXR5cGUsIGludGVnZXJfemVyb19ub2RlKSkpOwoJfQogICAgfQoKICBpZiAoMCAhPSAodmFsdWUgPSBjb25zdF9iaW5vcCAoTUlOVVNfRVhQUiwgaGlnaCwgbG93LCAwKSkKICAgICAgJiYgISBUUkVFX09WRVJGTE9XICh2YWx1ZSkpCiAgICByZXR1cm4gYnVpbGRfcmFuZ2VfY2hlY2sgKHR5cGUsCgkJCSAgICAgIGZvbGQgKGJ1aWxkIChNSU5VU19FWFBSLCBldHlwZSwgZXhwLCBsb3cpKSwKCQkJICAgICAgMSwgZm9sZF9jb252ZXJ0IChldHlwZSwgaW50ZWdlcl96ZXJvX25vZGUpLAoJCQkgICAgICB2YWx1ZSk7CgogIHJldHVybiAwOwp9CgwKLyogR2l2ZW4gdHdvIHJhbmdlcywgc2VlIGlmIHdlIGNhbiBtZXJnZSB0aGVtIGludG8gb25lLiAgUmV0dXJuIDEgaWYgd2UKICAgY2FuLCAwIGlmIHdlIGNhbid0LiAgU2V0IHRoZSBvdXRwdXQgcmFuZ2UgaW50byB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMuICAqLwoKc3RhdGljIGludAptZXJnZV9yYW5nZXMgKGludCAqcGluX3AsIHRyZWUgKnBsb3csIHRyZWUgKnBoaWdoLCBpbnQgaW4wX3AsIHRyZWUgbG93MCwKCSAgICAgIHRyZWUgaGlnaDAsIGludCBpbjFfcCwgdHJlZSBsb3cxLCB0cmVlIGhpZ2gxKQp7CiAgaW50IG5vX292ZXJsYXA7CiAgaW50IHN1YnNldDsKICBpbnQgdGVtcDsKICB0cmVlIHRlbTsKICBpbnQgaW5fcDsKICB0cmVlIGxvdywgaGlnaDsKICBpbnQgbG93ZXF1YWwgPSAoKGxvdzAgPT0gMCAmJiBsb3cxID09IDApCgkJICB8fCBpbnRlZ2VyX29uZXAgKHJhbmdlX2Jpbm9wIChFUV9FWFBSLCBpbnRlZ2VyX3R5cGVfbm9kZSwKCQkJCQkJbG93MCwgMCwgbG93MSwgMCkpKTsKICBpbnQgaGlnaGVxdWFsID0gKChoaWdoMCA9PSAwICYmIGhpZ2gxID09IDApCgkJICAgfHwgaW50ZWdlcl9vbmVwIChyYW5nZV9iaW5vcCAoRVFfRVhQUiwgaW50ZWdlcl90eXBlX25vZGUsCgkJCQkJCSBoaWdoMCwgMSwgaGlnaDEsIDEpKSk7CgogIC8qIE1ha2UgcmFuZ2UgMCBiZSB0aGUgcmFuZ2UgdGhhdCBzdGFydHMgZmlyc3QsIG9yIGVuZHMgbGFzdCBpZiB0aGV5CiAgICAgc3RhcnQgYXQgdGhlIHNhbWUgdmFsdWUuICBTd2FwIHRoZW0gaWYgaXQgaXNuJ3QuICAqLwogIGlmIChpbnRlZ2VyX29uZXAgKHJhbmdlX2Jpbm9wIChHVF9FWFBSLCBpbnRlZ2VyX3R5cGVfbm9kZSwKCQkJCSBsb3cwLCAwLCBsb3cxLCAwKSkKICAgICAgfHwgKGxvd2VxdWFsCgkgICYmIGludGVnZXJfb25lcCAocmFuZ2VfYmlub3AgKEdUX0VYUFIsIGludGVnZXJfdHlwZV9ub2RlLAoJCQkJCWhpZ2gxLCAxLCBoaWdoMCwgMSkpKSkKICAgIHsKICAgICAgdGVtcCA9IGluMF9wLCBpbjBfcCA9IGluMV9wLCBpbjFfcCA9IHRlbXA7CiAgICAgIHRlbSA9IGxvdzAsIGxvdzAgPSBsb3cxLCBsb3cxID0gdGVtOwogICAgICB0ZW0gPSBoaWdoMCwgaGlnaDAgPSBoaWdoMSwgaGlnaDEgPSB0ZW07CiAgICB9CgogIC8qIE5vdyBmbGFnIHR3byBjYXNlcywgd2hldGhlciB0aGUgcmFuZ2VzIGFyZSBkaXNqb2ludCBvciB3aGV0aGVyIHRoZQogICAgIHNlY29uZCByYW5nZSBpcyB0b3RhbGx5IHN1YnN1bWVkIGluIHRoZSBmaXJzdC4gIE5vdGUgdGhhdCB0aGUgdGVzdHMKICAgICBiZWxvdyBhcmUgc2ltcGxpZmllZCBieSB0aGUgb25lcyBhYm92ZS4gICovCiAgbm9fb3ZlcmxhcCA9IGludGVnZXJfb25lcCAocmFuZ2VfYmlub3AgKExUX0VYUFIsIGludGVnZXJfdHlwZV9ub2RlLAoJCQkJCSAgaGlnaDAsIDEsIGxvdzEsIDApKTsKICBzdWJzZXQgPSBpbnRlZ2VyX29uZXAgKHJhbmdlX2Jpbm9wIChMRV9FWFBSLCBpbnRlZ2VyX3R5cGVfbm9kZSwKCQkJCSAgICAgIGhpZ2gxLCAxLCBoaWdoMCwgMSkpOwoKICAvKiBXZSBub3cgaGF2ZSBmb3VyIGNhc2VzLCBkZXBlbmRpbmcgb24gd2hldGhlciB3ZSBhcmUgaW5jbHVkaW5nIG9yCiAgICAgZXhjbHVkaW5nIHRoZSB0d28gcmFuZ2VzLiAgKi8KICBpZiAoaW4wX3AgJiYgaW4xX3ApCiAgICB7CiAgICAgIC8qIElmIHRoZXkgZG9uJ3Qgb3ZlcmxhcCwgdGhlIHJlc3VsdCBpcyBmYWxzZS4gIElmIHRoZSBzZWNvbmQgcmFuZ2UKCSBpcyBhIHN1YnNldCBpdCBpcyB0aGUgcmVzdWx0LiAgT3RoZXJ3aXNlLCB0aGUgcmFuZ2UgaXMgZnJvbSB0aGUgc3RhcnQKCSBvZiB0aGUgc2Vjb25kIHRvIHRoZSBlbmQgb2YgdGhlIGZpcnN0LiAgKi8KICAgICAgaWYgKG5vX292ZXJsYXApCglpbl9wID0gMCwgbG93ID0gaGlnaCA9IDA7CiAgICAgIGVsc2UgaWYgKHN1YnNldCkKCWluX3AgPSAxLCBsb3cgPSBsb3cxLCBoaWdoID0gaGlnaDE7CiAgICAgIGVsc2UKCWluX3AgPSAxLCBsb3cgPSBsb3cxLCBoaWdoID0gaGlnaDA7CiAgICB9CgogIGVsc2UgaWYgKGluMF9wICYmICEgaW4xX3ApCiAgICB7CiAgICAgIC8qIElmIHRoZXkgZG9uJ3Qgb3ZlcmxhcCwgdGhlIHJlc3VsdCBpcyB0aGUgZmlyc3QgcmFuZ2UuICBJZiB0aGV5IGFyZQoJIGVxdWFsLCB0aGUgcmVzdWx0IGlzIGZhbHNlLiAgSWYgdGhlIHNlY29uZCByYW5nZSBpcyBhIHN1YnNldCBvZiB0aGUKCSBmaXJzdCwgYW5kIHRoZSByYW5nZXMgYmVnaW4gYXQgdGhlIHNhbWUgcGxhY2UsIHdlIGdvIGZyb20ganVzdCBhZnRlcgoJIHRoZSBlbmQgb2YgdGhlIGZpcnN0IHJhbmdlIHRvIHRoZSBlbmQgb2YgdGhlIHNlY29uZC4gIElmIHRoZSBzZWNvbmQKCSByYW5nZSBpcyBub3QgYSBzdWJzZXQgb2YgdGhlIGZpcnN0LCBvciBpZiBpdCBpcyBhIHN1YnNldCBhbmQgYm90aAoJIHJhbmdlcyBlbmQgYXQgdGhlIHNhbWUgcGxhY2UsIHRoZSByYW5nZSBzdGFydHMgYXQgdGhlIHN0YXJ0IG9mIHRoZQoJIGZpcnN0IHJhbmdlIGFuZCBlbmRzIGp1c3QgYmVmb3JlIHRoZSBzZWNvbmQgcmFuZ2UuCgkgT3RoZXJ3aXNlLCB3ZSBjYW4ndCBkZXNjcmliZSB0aGlzIGFzIGEgc2luZ2xlIHJhbmdlLiAgKi8KICAgICAgaWYgKG5vX292ZXJsYXApCglpbl9wID0gMSwgbG93ID0gbG93MCwgaGlnaCA9IGhpZ2gwOwogICAgICBlbHNlIGlmIChsb3dlcXVhbCAmJiBoaWdoZXF1YWwpCglpbl9wID0gMCwgbG93ID0gaGlnaCA9IDA7CiAgICAgIGVsc2UgaWYgKHN1YnNldCAmJiBsb3dlcXVhbCkKCXsKCSAgaW5fcCA9IDEsIGhpZ2ggPSBoaWdoMDsKCSAgbG93ID0gcmFuZ2VfYmlub3AgKFBMVVNfRVhQUiwgTlVMTF9UUkVFLCBoaWdoMSwgMCwKCQkJICAgICBpbnRlZ2VyX29uZV9ub2RlLCAwKTsKCX0KICAgICAgZWxzZSBpZiAoISBzdWJzZXQgfHwgaGlnaGVxdWFsKQoJewoJICBpbl9wID0gMSwgbG93ID0gbG93MDsKCSAgaGlnaCA9IHJhbmdlX2Jpbm9wIChNSU5VU19FWFBSLCBOVUxMX1RSRUUsIGxvdzEsIDAsCgkJCSAgICAgIGludGVnZXJfb25lX25vZGUsIDApOwoJfQogICAgICBlbHNlCglyZXR1cm4gMDsKICAgIH0KCiAgZWxzZSBpZiAoISBpbjBfcCAmJiBpbjFfcCkKICAgIHsKICAgICAgLyogSWYgdGhleSBkb24ndCBvdmVybGFwLCB0aGUgcmVzdWx0IGlzIHRoZSBzZWNvbmQgcmFuZ2UuICBJZiB0aGUgc2Vjb25kCgkgaXMgYSBzdWJzZXQgb2YgdGhlIGZpcnN0LCB0aGUgcmVzdWx0IGlzIGZhbHNlLiAgT3RoZXJ3aXNlLAoJIHRoZSByYW5nZSBzdGFydHMganVzdCBhZnRlciB0aGUgZmlyc3QgcmFuZ2UgYW5kIGVuZHMgYXQgdGhlCgkgZW5kIG9mIHRoZSBzZWNvbmQuICAqLwogICAgICBpZiAobm9fb3ZlcmxhcCkKCWluX3AgPSAxLCBsb3cgPSBsb3cxLCBoaWdoID0gaGlnaDE7CiAgICAgIGVsc2UgaWYgKHN1YnNldCB8fCBoaWdoZXF1YWwpCglpbl9wID0gMCwgbG93ID0gaGlnaCA9IDA7CiAgICAgIGVsc2UKCXsKCSAgaW5fcCA9IDEsIGhpZ2ggPSBoaWdoMTsKCSAgbG93ID0gcmFuZ2VfYmlub3AgKFBMVVNfRVhQUiwgTlVMTF9UUkVFLCBoaWdoMCwgMSwKCQkJICAgICBpbnRlZ2VyX29uZV9ub2RlLCAwKTsKCX0KICAgIH0KCiAgZWxzZQogICAgewogICAgICAvKiBUaGUgY2FzZSB3aGVyZSB3ZSBhcmUgZXhjbHVkaW5nIGJvdGggcmFuZ2VzLiAgSGVyZSB0aGUgY29tcGxleCBjYXNlCgkgaXMgaWYgdGhleSBkb24ndCBvdmVybGFwLiAgSW4gdGhhdCBjYXNlLCB0aGUgb25seSB0aW1lIHdlIGhhdmUgYQoJIHJhbmdlIGlzIGlmIHRoZXkgYXJlIGFkamFjZW50LiAgSWYgdGhlIHNlY29uZCBpcyBhIHN1YnNldCBvZiB0aGUKCSBmaXJzdCwgdGhlIHJlc3VsdCBpcyB0aGUgZmlyc3QuICBPdGhlcndpc2UsIHRoZSByYW5nZSB0byBleGNsdWRlCgkgc3RhcnRzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpcnN0IHJhbmdlIGFuZCBlbmRzIGF0IHRoZSBlbmQgb2YgdGhlCgkgc2Vjb25kLiAgKi8KICAgICAgaWYgKG5vX292ZXJsYXApCgl7CgkgIGlmIChpbnRlZ2VyX29uZXAgKHJhbmdlX2Jpbm9wIChFUV9FWFBSLCBpbnRlZ2VyX3R5cGVfbm9kZSwKCQkJCQkgcmFuZ2VfYmlub3AgKFBMVVNfRVhQUiwgTlVMTF9UUkVFLAoJCQkJCQkgICAgICBoaWdoMCwgMSwKCQkJCQkJICAgICAgaW50ZWdlcl9vbmVfbm9kZSwgMSksCgkJCQkJIDEsIGxvdzEsIDApKSkKCSAgICBpbl9wID0gMCwgbG93ID0gbG93MCwgaGlnaCA9IGhpZ2gxOwoJICBlbHNlCgkgICAgcmV0dXJuIDA7Cgl9CiAgICAgIGVsc2UgaWYgKHN1YnNldCkKCWluX3AgPSAwLCBsb3cgPSBsb3cwLCBoaWdoID0gaGlnaDA7CiAgICAgIGVsc2UKCWluX3AgPSAwLCBsb3cgPSBsb3cwLCBoaWdoID0gaGlnaDE7CiAgICB9CgogICpwaW5fcCA9IGluX3AsICpwbG93ID0gbG93LCAqcGhpZ2ggPSBoaWdoOwogIHJldHVybiAxOwp9CgwKI2lmbmRlZiBSQU5HRV9URVNUX05PTl9TSE9SVF9DSVJDVUlUCiNkZWZpbmUgUkFOR0VfVEVTVF9OT05fU0hPUlRfQ0lSQ1VJVCAoQlJBTkNIX0NPU1QgPj0gMikKI2VuZGlmCgovKiBFWFAgaXMgc29tZSBsb2dpY2FsIGNvbWJpbmF0aW9uIG9mIGJvb2xlYW4gdGVzdHMuICBTZWUgaWYgd2UgY2FuCiAgIG1lcmdlIGl0IGludG8gc29tZSByYW5nZSB0ZXN0LiAgUmV0dXJuIHRoZSBuZXcgdHJlZSBpZiBzby4gICovCgpzdGF0aWMgdHJlZQpmb2xkX3JhbmdlX3Rlc3QgKHRyZWUgZXhwKQp7CiAgaW50IG9yX29wID0gKFRSRUVfQ09ERSAoZXhwKSA9PSBUUlVUSF9PUklGX0VYUFIKCSAgICAgICB8fCBUUkVFX0NPREUgKGV4cCkgPT0gVFJVVEhfT1JfRVhQUik7CiAgaW50IGluMF9wLCBpbjFfcCwgaW5fcDsKICB0cmVlIGxvdzAsIGxvdzEsIGxvdywgaGlnaDAsIGhpZ2gxLCBoaWdoOwogIHRyZWUgbGhzID0gbWFrZV9yYW5nZSAoVFJFRV9PUEVSQU5EIChleHAsIDApLCAmaW4wX3AsICZsb3cwLCAmaGlnaDApOwogIHRyZWUgcmhzID0gbWFrZV9yYW5nZSAoVFJFRV9PUEVSQU5EIChleHAsIDEpLCAmaW4xX3AsICZsb3cxLCAmaGlnaDEpOwogIHRyZWUgdGVtOwoKICAvKiBJZiB0aGlzIGlzIGFuIE9SIG9wZXJhdGlvbiwgaW52ZXJ0IGJvdGggc2lkZXM7IHdlIHdpbGwgaW52ZXJ0CiAgICAgYWdhaW4gYXQgdGhlIGVuZC4gICovCiAgaWYgKG9yX29wKQogICAgaW4wX3AgPSAhIGluMF9wLCBpbjFfcCA9ICEgaW4xX3A7CgogIC8qIElmIGJvdGggZXhwcmVzc2lvbnMgYXJlIHRoZSBzYW1lLCBpZiB3ZSBjYW4gbWVyZ2UgdGhlIHJhbmdlcywgYW5kIHdlCiAgICAgY2FuIGJ1aWxkIHRoZSByYW5nZSB0ZXN0LCByZXR1cm4gaXQgb3IgaXQgaW52ZXJ0ZWQuICBJZiBvbmUgb2YgdGhlCiAgICAgcmFuZ2VzIGlzIGFsd2F5cyB0cnVlIG9yIGFsd2F5cyBmYWxzZSwgY29uc2lkZXIgaXQgdG8gYmUgdGhlIHNhbWUKICAgICBleHByZXNzaW9uIGFzIHRoZSBvdGhlci4gICovCiAgaWYgKChsaHMgPT0gMCB8fCByaHMgPT0gMCB8fCBvcGVyYW5kX2VxdWFsX3AgKGxocywgcmhzLCAwKSkKICAgICAgJiYgbWVyZ2VfcmFuZ2VzICgmaW5fcCwgJmxvdywgJmhpZ2gsIGluMF9wLCBsb3cwLCBoaWdoMCwKCQkgICAgICAgaW4xX3AsIGxvdzEsIGhpZ2gxKQogICAgICAmJiAwICE9ICh0ZW0gPSAoYnVpbGRfcmFuZ2VfY2hlY2sgKFRSRUVfVFlQRSAoZXhwKSwKCQkJCQkgbGhzICE9IDAgPyBsaHMKCQkJCQkgOiByaHMgIT0gMCA/IHJocyA6IGludGVnZXJfemVyb19ub2RlLAoJCQkJCSBpbl9wLCBsb3csIGhpZ2gpKSkpCiAgICByZXR1cm4gb3Jfb3AgPyBpbnZlcnRfdHJ1dGh2YWx1ZSAodGVtKSA6IHRlbTsKCiAgLyogT24gbWFjaGluZXMgd2hlcmUgdGhlIGJyYW5jaCBjb3N0IGlzIGV4cGVuc2l2ZSwgaWYgdGhpcyBpcyBhCiAgICAgc2hvcnQtY2lyY3VpdGVkIGJyYW5jaCBhbmQgdGhlIHVuZGVybHlpbmcgb2JqZWN0IG9uIGJvdGggc2lkZXMKICAgICBpcyB0aGUgc2FtZSwgbWFrZSBhIG5vbi1zaG9ydC1jaXJjdWl0IG9wZXJhdGlvbi4gICovCiAgZWxzZSBpZiAoUkFOR0VfVEVTVF9OT05fU0hPUlRfQ0lSQ1VJVAoJICAgJiYgbGhzICE9IDAgJiYgcmhzICE9IDAKCSAgICYmIChUUkVFX0NPREUgKGV4cCkgPT0gVFJVVEhfQU5ESUZfRVhQUgoJICAgICAgIHx8IFRSRUVfQ09ERSAoZXhwKSA9PSBUUlVUSF9PUklGX0VYUFIpCgkgICAmJiBvcGVyYW5kX2VxdWFsX3AgKGxocywgcmhzLCAwKSkKICAgIHsKICAgICAgLyogSWYgc2ltcGxlIGVub3VnaCwganVzdCByZXdyaXRlLiAgT3RoZXJ3aXNlLCBtYWtlIGEgU0FWRV9FWFBSCgkgdW5sZXNzIHdlIGFyZSBhdCB0b3AgbGV2ZWwgb3IgTEhTIGNvbnRhaW5zIGEgUExBQ0VIT0xERVJfRVhQUiwgaW4KCSB3aGljaCBjYXNlcyB3ZSBjYW4ndCBkbyB0aGlzLiAgKi8KICAgICAgaWYgKHNpbXBsZV9vcGVyYW5kX3AgKGxocykpCglyZXR1cm4gYnVpbGQgKFRSRUVfQ09ERSAoZXhwKSA9PSBUUlVUSF9BTkRJRl9FWFBSCgkJICAgICAgPyBUUlVUSF9BTkRfRVhQUiA6IFRSVVRIX09SX0VYUFIsCgkJICAgICAgVFJFRV9UWVBFIChleHApLCBUUkVFX09QRVJBTkQgKGV4cCwgMCksCgkJICAgICAgVFJFRV9PUEVSQU5EIChleHAsIDEpKTsKCiAgICAgIGVsc2UgaWYgKCgqbGFuZ19ob29rcy5kZWNscy5nbG9iYWxfYmluZGluZ3NfcCkgKCkgPT0gMAoJICAgICAgICYmICEgQ09OVEFJTlNfUExBQ0VIT0xERVJfUCAobGhzKSkKCXsKCSAgdHJlZSBjb21tb24gPSBzYXZlX2V4cHIgKGxocyk7CgoJICBpZiAoMCAhPSAobGhzID0gYnVpbGRfcmFuZ2VfY2hlY2sgKFRSRUVfVFlQRSAoZXhwKSwgY29tbW9uLAoJCQkJCSAgICAgb3Jfb3AgPyAhIGluMF9wIDogaW4wX3AsCgkJCQkJICAgICBsb3cwLCBoaWdoMCkpCgkgICAgICAmJiAoMCAhPSAocmhzID0gYnVpbGRfcmFuZ2VfY2hlY2sgKFRSRUVfVFlQRSAoZXhwKSwgY29tbW9uLAoJCQkJCQkgb3Jfb3AgPyAhIGluMV9wIDogaW4xX3AsCgkJCQkJCSBsb3cxLCBoaWdoMSkpKSkKCSAgICByZXR1cm4gYnVpbGQgKFRSRUVfQ09ERSAoZXhwKSA9PSBUUlVUSF9BTkRJRl9FWFBSCgkJCSAgPyBUUlVUSF9BTkRfRVhQUiA6IFRSVVRIX09SX0VYUFIsCgkJCSAgVFJFRV9UWVBFIChleHApLCBsaHMsIHJocyk7Cgl9CiAgICB9CgogIHJldHVybiAwOwp9CgwKLyogU3Vicm91dGluZSBmb3IgZm9sZF90cnV0aG9wOiBDIGlzIGFuIElOVEVHRVJfQ1NUIGludGVycHJldGVkIGFzIGEgUAogICBiaXQgdmFsdWUuICBBcnJhbmdlIHRoaW5ncyBzbyB0aGUgZXh0cmEgYml0cyB3aWxsIGJlIHNldCB0byB6ZXJvIGlmIGFuZAogICBvbmx5IGlmIEMgaXMgc2lnbmVkLWV4dGVuZGVkIHRvIGl0cyBmdWxsIHdpZHRoLiAgSWYgTUFTSyBpcyBub256ZXJvLAogICBpdCBpcyBhbiBJTlRFR0VSX0NTVCB0aGF0IHNob3VsZCBiZSBBTkQnZWQgd2l0aCB0aGUgZXh0cmEgYml0cy4gICovCgpzdGF0aWMgdHJlZQp1bmV4dGVuZCAodHJlZSBjLCBpbnQgcCwgaW50IHVuc2lnbmVkcCwgdHJlZSBtYXNrKQp7CiAgdHJlZSB0eXBlID0gVFJFRV9UWVBFIChjKTsKICBpbnQgbW9kZXNpemUgPSBHRVRfTU9ERV9CSVRTSVpFIChUWVBFX01PREUgKHR5cGUpKTsKICB0cmVlIHRlbXA7CgogIGlmIChwID09IG1vZGVzaXplIHx8IHVuc2lnbmVkcCkKICAgIHJldHVybiBjOwoKICAvKiBXZSB3b3JrIGJ5IGdldHRpbmcganVzdCB0aGUgc2lnbiBiaXQgaW50byB0aGUgbG93LW9yZGVyIGJpdCwgdGhlbgogICAgIGludG8gdGhlIGhpZ2gtb3JkZXIgYml0LCB0aGVuIHNpZ24tZXh0ZW5kLiAgV2UgdGhlbiBYT1IgdGhhdCB2YWx1ZQogICAgIHdpdGggQy4gICovCiAgdGVtcCA9IGNvbnN0X2Jpbm9wIChSU0hJRlRfRVhQUiwgYywgc2l6ZV9pbnQgKHAgLSAxKSwgMCk7CiAgdGVtcCA9IGNvbnN0X2Jpbm9wIChCSVRfQU5EX0VYUFIsIHRlbXAsIHNpemVfaW50ICgxKSwgMCk7CgogIC8qIFdlIG11c3QgdXNlIGEgc2lnbmVkIHR5cGUgaW4gb3JkZXIgdG8gZ2V0IGFuIGFyaXRobWV0aWMgcmlnaHQgc2hpZnQuCiAgICAgSG93ZXZlciwgd2UgbXVzdCBhbHNvIGF2b2lkIGludHJvZHVjaW5nIGFjY2lkZW50YWwgb3ZlcmZsb3dzLCBzbyB0aGF0CiAgICAgYSBzdWJzZXF1ZW50IGNhbGwgdG8gaW50ZWdlcl96ZXJvcCB3aWxsIHdvcmsuICBIZW5jZSB3ZSBtdXN0CiAgICAgZG8gdGhlIHR5cGUgY29udmVyc2lvbiBoZXJlLiAgQXQgdGhpcyBwb2ludCwgdGhlIGNvbnN0YW50IGlzIGVpdGhlcgogICAgIHplcm8gb3Igb25lLCBhbmQgdGhlIGNvbnZlcnNpb24gdG8gYSBzaWduZWQgdHlwZSBjYW4gbmV2ZXIgb3ZlcmZsb3cuCiAgICAgV2UgY291bGQgZ2V0IGFuIG92ZXJmbG93IGlmIHRoaXMgY29udmVyc2lvbiBpcyBkb25lIGFueXdoZXJlIGVsc2UuICAqLwogIGlmIChUUkVFX1VOU0lHTkVEICh0eXBlKSkKICAgIHRlbXAgPSBmb2xkX2NvbnZlcnQgKCgqbGFuZ19ob29rcy50eXBlcy5zaWduZWRfdHlwZSkgKHR5cGUpLCB0ZW1wKTsKCiAgdGVtcCA9IGNvbnN0X2Jpbm9wIChMU0hJRlRfRVhQUiwgdGVtcCwgc2l6ZV9pbnQgKG1vZGVzaXplIC0gMSksIDApOwogIHRlbXAgPSBjb25zdF9iaW5vcCAoUlNISUZUX0VYUFIsIHRlbXAsIHNpemVfaW50IChtb2Rlc2l6ZSAtIHAgLSAxKSwgMCk7CiAgaWYgKG1hc2sgIT0gMCkKICAgIHRlbXAgPSBjb25zdF9iaW5vcCAoQklUX0FORF9FWFBSLCB0ZW1wLAoJCQlmb2xkX2NvbnZlcnQgKFRSRUVfVFlQRSAoYyksIG1hc2spLCAwKTsKICAvKiBJZiBuZWNlc3NhcnksIGNvbnZlcnQgdGhlIHR5cGUgYmFjayB0byBtYXRjaCB0aGUgdHlwZSBvZiBDLiAgKi8KICBpZiAoVFJFRV9VTlNJR05FRCAodHlwZSkpCiAgICB0ZW1wID0gZm9sZF9jb252ZXJ0ICh0eXBlLCB0ZW1wKTsKCiAgcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgY29uc3RfYmlub3AgKEJJVF9YT1JfRVhQUiwgYywgdGVtcCwgMCkpOwp9CgwKLyogRmluZCB3YXlzIG9mIGZvbGRpbmcgbG9naWNhbCBleHByZXNzaW9ucyBvZiBMSFMgYW5kIFJIUzoKICAgVHJ5IHRvIG1lcmdlIHR3byBjb21wYXJpc29ucyB0byB0aGUgc2FtZSBpbm5lcm1vc3QgaXRlbS4KICAgTG9vayBmb3IgcmFuZ2UgdGVzdHMgbGlrZSAiY2ggPj0gJzAnICYmIGNoIDw9ICc5JyIuCiAgIExvb2sgZm9yIGNvbWJpbmF0aW9ucyBvZiBzaW1wbGUgdGVybXMgb24gbWFjaGluZXMgd2l0aCBleHBlbnNpdmUgYnJhbmNoZXMKICAgYW5kIGV2YWx1YXRlIHRoZSBSSFMgdW5jb25kaXRpb25hbGx5LgoKICAgRm9yIGV4YW1wbGUsIGlmIHdlIGhhdmUgcC0+YSA9PSAyICYmIHAtPmIgPT0gNCBhbmQgd2UgY2FuIG1ha2UgYW4KICAgb2JqZWN0IGxhcmdlIGVub3VnaCB0byBzcGFuIGJvdGggQSBhbmQgQiwgd2UgY2FuIGRvIHRoaXMgd2l0aCBhIGNvbXBhcmlzb24KICAgYWdhaW5zdCB0aGUgb2JqZWN0IEFORGVkIHdpdGggdGhlIGEgbWFzay4KCiAgIElmIHdlIGhhdmUgcC0+YSA9PSBxLT5hICYmIHAtPmIgPT0gcS0+Yiwgd2UgbWF5IGJlIGFibGUgdG8gdXNlIGJpdCBtYXNraW5nCiAgIG9wZXJhdGlvbnMgdG8gZG8gdGhpcyB3aXRoIG9uZSBjb21wYXJpc29uLgoKICAgV2UgY2hlY2sgZm9yIGJvdGggbm9ybWFsIGNvbXBhcmlzb25zIGFuZCB0aGUgQklUX0FORF9FWFBScyBtYWRlIHRoaXMgYnkKICAgZnVuY3Rpb24gYW5kIHRoZSBvbmUgYWJvdmUuCgogICBDT0RFIGlzIHRoZSBsb2dpY2FsIG9wZXJhdGlvbiBiZWluZyBkb25lLiAgSXQgY2FuIGJlIFRSVVRIX0FORElGX0VYUFIsCiAgIFRSVVRIX0FORF9FWFBSLCBUUlVUSF9PUklGX0VYUFIsIG9yIFRSVVRIX09SX0VYUFIuCgogICBUUlVUSF9UWVBFIGlzIHRoZSB0eXBlIG9mIHRoZSBsb2dpY2FsIG9wZXJhbmQgYW5kIExIUyBhbmQgUkhTIGFyZSBpdHMKICAgdHdvIG9wZXJhbmRzLgoKICAgV2UgcmV0dXJuIHRoZSBzaW1wbGlmaWVkIHRyZWUgb3IgMCBpZiBubyBvcHRpbWl6YXRpb24gaXMgcG9zc2libGUuICAqLwoKc3RhdGljIHRyZWUKZm9sZF90cnV0aG9wIChlbnVtIHRyZWVfY29kZSBjb2RlLCB0cmVlIHRydXRoX3R5cGUsIHRyZWUgbGhzLCB0cmVlIHJocykKewogIC8qIElmIHRoaXMgaXMgdGhlICJvciIgb2YgdHdvIGNvbXBhcmlzb25zLCB3ZSBjYW4gZG8gc29tZXRoaW5nIGlmCiAgICAgdGhlIGNvbXBhcmlzb25zIGFyZSBORV9FWFBSLiAgSWYgdGhpcyBpcyB0aGUgImFuZCIsIHdlIGNhbiBkbyBzb21ldGhpbmcKICAgICBpZiB0aGUgY29tcGFyaXNvbnMgYXJlIEVRX0VYUFIuICBJLmUuLAoJKGEtPmIgPT0gMiAmJiBhLT5jID09IDQpIGNhbiBiZWNvbWUgKGEtPm5ldyA9PSBORVcpLgoKICAgICBXQU5URURfQ09ERSBpcyB0aGlzIG9wZXJhdGlvbiBjb2RlLiAgRm9yIHNpbmdsZSBiaXQgZmllbGRzLCB3ZSBjYW4KICAgICBjb252ZXJ0IEVRX0VYUFIgdG8gTkVfRVhQUiBzbyB3ZSBuZWVkIG5vdCByZWplY3QgdGhlICJ3cm9uZyIKICAgICBjb21wYXJpc29uIGZvciBvbmUtYml0IGZpZWxkcy4gICovCgogIGVudW0gdHJlZV9jb2RlIHdhbnRlZF9jb2RlOwogIGVudW0gdHJlZV9jb2RlIGxjb2RlLCByY29kZTsKICB0cmVlIGxsX2FyZywgbHJfYXJnLCBybF9hcmcsIHJyX2FyZzsKICB0cmVlIGxsX2lubmVyLCBscl9pbm5lciwgcmxfaW5uZXIsIHJyX2lubmVyOwogIEhPU1RfV0lERV9JTlQgbGxfYml0c2l6ZSwgbGxfYml0cG9zLCBscl9iaXRzaXplLCBscl9iaXRwb3M7CiAgSE9TVF9XSURFX0lOVCBybF9iaXRzaXplLCBybF9iaXRwb3MsIHJyX2JpdHNpemUsIHJyX2JpdHBvczsKICBIT1NUX1dJREVfSU5UIHhsbF9iaXRwb3MsIHhscl9iaXRwb3MsIHhybF9iaXRwb3MsIHhycl9iaXRwb3M7CiAgSE9TVF9XSURFX0lOVCBsbmJpdHNpemUsIGxuYml0cG9zLCBybmJpdHNpemUsIHJuYml0cG9zOwogIGludCBsbF91bnNpZ25lZHAsIGxyX3Vuc2lnbmVkcCwgcmxfdW5zaWduZWRwLCBycl91bnNpZ25lZHA7CiAgZW51bSBtYWNoaW5lX21vZGUgbGxfbW9kZSwgbHJfbW9kZSwgcmxfbW9kZSwgcnJfbW9kZTsKICBlbnVtIG1hY2hpbmVfbW9kZSBsbm1vZGUsIHJubW9kZTsKICB0cmVlIGxsX21hc2ssIGxyX21hc2ssIHJsX21hc2ssIHJyX21hc2s7CiAgdHJlZSBsbF9hbmRfbWFzaywgbHJfYW5kX21hc2ssIHJsX2FuZF9tYXNrLCBycl9hbmRfbWFzazsKICB0cmVlIGxfY29uc3QsIHJfY29uc3Q7CiAgdHJlZSBsbnR5cGUsIHJudHlwZSwgcmVzdWx0OwogIGludCBmaXJzdF9iaXQsIGVuZF9iaXQ7CiAgaW50IHZvbGF0aWxlcDsKCiAgLyogU3RhcnQgYnkgZ2V0dGluZyB0aGUgY29tcGFyaXNvbiBjb2Rlcy4gIEZhaWwgaWYgYW55dGhpbmcgaXMgdm9sYXRpbGUuCiAgICAgSWYgb25lIG9wZXJhbmQgaXMgYSBCSVRfQU5EX0VYUFIgd2l0aCB0aGUgY29uc3RhbnQgb25lLCB0cmVhdCBpdCBhcyBpZgogICAgIGl0IHdlcmUgc3Vycm91bmRlZCB3aXRoIGEgTkVfRVhQUi4gICovCgogIGlmIChUUkVFX1NJREVfRUZGRUNUUyAobGhzKSB8fCBUUkVFX1NJREVfRUZGRUNUUyAocmhzKSkKICAgIHJldHVybiAwOwoKICBsY29kZSA9IFRSRUVfQ09ERSAobGhzKTsKICByY29kZSA9IFRSRUVfQ09ERSAocmhzKTsKCiAgaWYgKGxjb2RlID09IEJJVF9BTkRfRVhQUiAmJiBpbnRlZ2VyX29uZXAgKFRSRUVfT1BFUkFORCAobGhzLCAxKSkpCiAgICBsY29kZSA9IE5FX0VYUFIsIGxocyA9IGJ1aWxkIChORV9FWFBSLCB0cnV0aF90eXBlLCBsaHMsIGludGVnZXJfemVyb19ub2RlKTsKCiAgaWYgKHJjb2RlID09IEJJVF9BTkRfRVhQUiAmJiBpbnRlZ2VyX29uZXAgKFRSRUVfT1BFUkFORCAocmhzLCAxKSkpCiAgICByY29kZSA9IE5FX0VYUFIsIHJocyA9IGJ1aWxkIChORV9FWFBSLCB0cnV0aF90eXBlLCByaHMsIGludGVnZXJfemVyb19ub2RlKTsKCiAgaWYgKFRSRUVfQ09ERV9DTEFTUyAobGNvZGUpICE9ICc8JyB8fCBUUkVFX0NPREVfQ0xBU1MgKHJjb2RlKSAhPSAnPCcpCiAgICByZXR1cm4gMDsKCiAgY29kZSA9ICgoY29kZSA9PSBUUlVUSF9BTkRfRVhQUiB8fCBjb2RlID09IFRSVVRIX0FORElGX0VYUFIpCgkgID8gVFJVVEhfQU5EX0VYUFIgOiBUUlVUSF9PUl9FWFBSKTsKCiAgbGxfYXJnID0gVFJFRV9PUEVSQU5EIChsaHMsIDApOwogIGxyX2FyZyA9IFRSRUVfT1BFUkFORCAobGhzLCAxKTsKICBybF9hcmcgPSBUUkVFX09QRVJBTkQgKHJocywgMCk7CiAgcnJfYXJnID0gVFJFRV9PUEVSQU5EIChyaHMsIDEpOwoKICAvKiBTaW1wbGlmeSAoeDx5KSAmJiAoeD09eSkgaW50byAoeDw9eSkgYW5kIHJlbGF0ZWQgb3B0aW1pemF0aW9ucy4gICovCiAgaWYgKHNpbXBsZV9vcGVyYW5kX3AgKGxsX2FyZykKICAgICAgJiYgc2ltcGxlX29wZXJhbmRfcCAobHJfYXJnKQogICAgICAmJiAhRkxPQVRfVFlQRV9QIChUUkVFX1RZUEUgKGxsX2FyZykpKQogICAgewogICAgICBpbnQgY29tcGNvZGU7CgogICAgICBpZiAob3BlcmFuZF9lcXVhbF9wIChsbF9hcmcsIHJsX2FyZywgMCkKICAgICAgICAgICYmIG9wZXJhbmRfZXF1YWxfcCAobHJfYXJnLCBycl9hcmcsIDApKQogICAgICAgIHsKICAgICAgICAgIGludCBsY29tcGNvZGUsIHJjb21wY29kZTsKCiAgICAgICAgICBsY29tcGNvZGUgPSBjb21wYXJpc29uX3RvX2NvbXBjb2RlIChsY29kZSk7CiAgICAgICAgICByY29tcGNvZGUgPSBjb21wYXJpc29uX3RvX2NvbXBjb2RlIChyY29kZSk7CiAgICAgICAgICBjb21wY29kZSA9IChjb2RlID09IFRSVVRIX0FORF9FWFBSKQogICAgICAgICAgICAgICAgICAgICA/IGxjb21wY29kZSAmIHJjb21wY29kZQogICAgICAgICAgICAgICAgICAgICA6IGxjb21wY29kZSB8IHJjb21wY29kZTsKICAgICAgICB9CiAgICAgIGVsc2UgaWYgKG9wZXJhbmRfZXF1YWxfcCAobGxfYXJnLCBycl9hcmcsIDApCiAgICAgICAgICAgICAgICYmIG9wZXJhbmRfZXF1YWxfcCAobHJfYXJnLCBybF9hcmcsIDApKQogICAgICAgIHsKICAgICAgICAgIGludCBsY29tcGNvZGUsIHJjb21wY29kZTsKCiAgICAgICAgICByY29kZSA9IHN3YXBfdHJlZV9jb21wYXJpc29uIChyY29kZSk7CiAgICAgICAgICBsY29tcGNvZGUgPSBjb21wYXJpc29uX3RvX2NvbXBjb2RlIChsY29kZSk7CiAgICAgICAgICByY29tcGNvZGUgPSBjb21wYXJpc29uX3RvX2NvbXBjb2RlIChyY29kZSk7CiAgICAgICAgICBjb21wY29kZSA9IChjb2RlID09IFRSVVRIX0FORF9FWFBSKQogICAgICAgICAgICAgICAgICAgICA/IGxjb21wY29kZSAmIHJjb21wY29kZQogICAgICAgICAgICAgICAgICAgICA6IGxjb21wY29kZSB8IHJjb21wY29kZTsKICAgICAgICB9CiAgICAgIGVsc2UKCWNvbXBjb2RlID0gLTE7CgogICAgICBpZiAoY29tcGNvZGUgPT0gQ09NUENPREVfVFJVRSkKCXJldHVybiBmb2xkX2NvbnZlcnQgKHRydXRoX3R5cGUsIGludGVnZXJfb25lX25vZGUpOwogICAgICBlbHNlIGlmIChjb21wY29kZSA9PSBDT01QQ09ERV9GQUxTRSkKCXJldHVybiBmb2xkX2NvbnZlcnQgKHRydXRoX3R5cGUsIGludGVnZXJfemVyb19ub2RlKTsKICAgICAgZWxzZSBpZiAoY29tcGNvZGUgIT0gLTEpCglyZXR1cm4gYnVpbGQgKGNvbXBjb2RlX3RvX2NvbXBhcmlzb24gKGNvbXBjb2RlKSwKCQkgICAgICB0cnV0aF90eXBlLCBsbF9hcmcsIGxyX2FyZyk7CiAgICB9CgogIC8qIElmIHRoZSBSSFMgY2FuIGJlIGV2YWx1YXRlZCB1bmNvbmRpdGlvbmFsbHkgYW5kIGl0cyBvcGVyYW5kcyBhcmUKICAgICBzaW1wbGUsIGl0IHdpbnMgdG8gZXZhbHVhdGUgdGhlIFJIUyB1bmNvbmRpdGlvbmFsbHkgb24gbWFjaGluZXMKICAgICB3aXRoIGV4cGVuc2l2ZSBicmFuY2hlcy4gIEluIHRoaXMgY2FzZSwgdGhpcyBpc24ndCBhIGNvbXBhcmlzb24KICAgICB0aGF0IGNhbiBiZSBtZXJnZWQuICBBdm9pZCBkb2luZyB0aGlzIGlmIHRoZSBSSFMgaXMgYSBmbG9hdGluZy1wb2ludAogICAgIGNvbXBhcmlzb24gc2luY2UgdGhvc2UgY2FuIHRyYXAuICAqLwoKICBpZiAoQlJBTkNIX0NPU1QgPj0gMgogICAgICAmJiAhIEZMT0FUX1RZUEVfUCAoVFJFRV9UWVBFIChybF9hcmcpKQogICAgICAmJiBzaW1wbGVfb3BlcmFuZF9wIChybF9hcmcpCiAgICAgICYmIHNpbXBsZV9vcGVyYW5kX3AgKHJyX2FyZykpCiAgICB7CiAgICAgIC8qIENvbnZlcnQgKGEgIT0gMCkgfHwgKGIgIT0gMCkgaW50byAoYSB8IGIpICE9IDAuICAqLwogICAgICBpZiAoY29kZSA9PSBUUlVUSF9PUl9FWFBSCgkgICYmIGxjb2RlID09IE5FX0VYUFIgJiYgaW50ZWdlcl96ZXJvcCAobHJfYXJnKQoJICAmJiByY29kZSA9PSBORV9FWFBSICYmIGludGVnZXJfemVyb3AgKHJyX2FyZykKCSAgJiYgVFJFRV9UWVBFIChsbF9hcmcpID09IFRSRUVfVFlQRSAocmxfYXJnKSkKCXJldHVybiBidWlsZCAoTkVfRVhQUiwgdHJ1dGhfdHlwZSwKCQkgICAgICBidWlsZCAoQklUX0lPUl9FWFBSLCBUUkVFX1RZUEUgKGxsX2FyZyksCgkJCSAgICAgbGxfYXJnLCBybF9hcmcpLAoJCSAgICAgIGludGVnZXJfemVyb19ub2RlKTsKCiAgICAgIC8qIENvbnZlcnQgKGEgPT0gMCkgJiYgKGIgPT0gMCkgaW50byAoYSB8IGIpID09IDAuICAqLwogICAgICBpZiAoY29kZSA9PSBUUlVUSF9BTkRfRVhQUgoJICAmJiBsY29kZSA9PSBFUV9FWFBSICYmIGludGVnZXJfemVyb3AgKGxyX2FyZykKCSAgJiYgcmNvZGUgPT0gRVFfRVhQUiAmJiBpbnRlZ2VyX3plcm9wIChycl9hcmcpCgkgICYmIFRSRUVfVFlQRSAobGxfYXJnKSA9PSBUUkVFX1RZUEUgKHJsX2FyZykpCglyZXR1cm4gYnVpbGQgKEVRX0VYUFIsIHRydXRoX3R5cGUsCgkJICAgICAgYnVpbGQgKEJJVF9JT1JfRVhQUiwgVFJFRV9UWVBFIChsbF9hcmcpLAoJCQkgICAgIGxsX2FyZywgcmxfYXJnKSwKCQkgICAgICBpbnRlZ2VyX3plcm9fbm9kZSk7CgogICAgICByZXR1cm4gYnVpbGQgKGNvZGUsIHRydXRoX3R5cGUsIGxocywgcmhzKTsKICAgIH0KCiAgLyogU2VlIGlmIHRoZSBjb21wYXJpc29ucyBjYW4gYmUgbWVyZ2VkLiAgVGhlbiBnZXQgYWxsIHRoZSBwYXJhbWV0ZXJzIGZvcgogICAgIGVhY2ggc2lkZS4gICovCgogIGlmICgobGNvZGUgIT0gRVFfRVhQUiAmJiBsY29kZSAhPSBORV9FWFBSKQogICAgICB8fCAocmNvZGUgIT0gRVFfRVhQUiAmJiByY29kZSAhPSBORV9FWFBSKSkKICAgIHJldHVybiAwOwoKICB2b2xhdGlsZXAgPSAwOwogIGxsX2lubmVyID0gZGVjb2RlX2ZpZWxkX3JlZmVyZW5jZSAobGxfYXJnLAoJCQkJICAgICAmbGxfYml0c2l6ZSwgJmxsX2JpdHBvcywgJmxsX21vZGUsCgkJCQkgICAgICZsbF91bnNpZ25lZHAsICZ2b2xhdGlsZXAsICZsbF9tYXNrLAoJCQkJICAgICAmbGxfYW5kX21hc2spOwogIGxyX2lubmVyID0gZGVjb2RlX2ZpZWxkX3JlZmVyZW5jZSAobHJfYXJnLAoJCQkJICAgICAmbHJfYml0c2l6ZSwgJmxyX2JpdHBvcywgJmxyX21vZGUsCgkJCQkgICAgICZscl91bnNpZ25lZHAsICZ2b2xhdGlsZXAsICZscl9tYXNrLAoJCQkJICAgICAmbHJfYW5kX21hc2spOwogIHJsX2lubmVyID0gZGVjb2RlX2ZpZWxkX3JlZmVyZW5jZSAocmxfYXJnLAoJCQkJICAgICAmcmxfYml0c2l6ZSwgJnJsX2JpdHBvcywgJnJsX21vZGUsCgkJCQkgICAgICZybF91bnNpZ25lZHAsICZ2b2xhdGlsZXAsICZybF9tYXNrLAoJCQkJICAgICAmcmxfYW5kX21hc2spOwogIHJyX2lubmVyID0gZGVjb2RlX2ZpZWxkX3JlZmVyZW5jZSAocnJfYXJnLAoJCQkJICAgICAmcnJfYml0c2l6ZSwgJnJyX2JpdHBvcywgJnJyX21vZGUsCgkJCQkgICAgICZycl91bnNpZ25lZHAsICZ2b2xhdGlsZXAsICZycl9tYXNrLAoJCQkJICAgICAmcnJfYW5kX21hc2spOwoKICAvKiBJdCBtdXN0IGJlIHRydWUgdGhhdCB0aGUgaW5uZXIgb3BlcmF0aW9uIG9uIHRoZSBsaHMgb2YgZWFjaAogICAgIGNvbXBhcmlzb24gbXVzdCBiZSB0aGUgc2FtZSBpZiB3ZSBhcmUgdG8gYmUgYWJsZSB0byBkbyBhbnl0aGluZy4KICAgICBUaGVuIHNlZSBpZiB3ZSBoYXZlIGNvbnN0YW50cy4gIElmIG5vdCwgdGhlIHNhbWUgbXVzdCBiZSB0cnVlIGZvcgogICAgIHRoZSByaHMncy4gICovCiAgaWYgKHZvbGF0aWxlcCB8fCBsbF9pbm5lciA9PSAwIHx8IHJsX2lubmVyID09IDAKICAgICAgfHwgISBvcGVyYW5kX2VxdWFsX3AgKGxsX2lubmVyLCBybF9pbm5lciwgMCkpCiAgICByZXR1cm4gMDsKCiAgaWYgKFRSRUVfQ09ERSAobHJfYXJnKSA9PSBJTlRFR0VSX0NTVAogICAgICAmJiBUUkVFX0NPREUgKHJyX2FyZykgPT0gSU5URUdFUl9DU1QpCiAgICBsX2NvbnN0ID0gbHJfYXJnLCByX2NvbnN0ID0gcnJfYXJnOwogIGVsc2UgaWYgKGxyX2lubmVyID09IDAgfHwgcnJfaW5uZXIgPT0gMAoJICAgfHwgISBvcGVyYW5kX2VxdWFsX3AgKGxyX2lubmVyLCBycl9pbm5lciwgMCkpCiAgICByZXR1cm4gMDsKICBlbHNlCiAgICBsX2NvbnN0ID0gcl9jb25zdCA9IDA7CgogIC8qIElmIGVpdGhlciBjb21wYXJpc29uIGNvZGUgaXMgbm90IGNvcnJlY3QgZm9yIG91ciBsb2dpY2FsIG9wZXJhdGlvbiwKICAgICBmYWlsLiAgSG93ZXZlciwgd2UgY2FuIGNvbnZlcnQgYSBvbmUtYml0IGNvbXBhcmlzb24gYWdhaW5zdCB6ZXJvIGludG8KICAgICB0aGUgb3Bwb3NpdGUgY29tcGFyaXNvbiBhZ2FpbnN0IHRoYXQgYml0IGJlaW5nIHNldCBpbiB0aGUgZmllbGQuICAqLwoKICB3YW50ZWRfY29kZSA9IChjb2RlID09IFRSVVRIX0FORF9FWFBSID8gRVFfRVhQUiA6IE5FX0VYUFIpOwogIGlmIChsY29kZSAhPSB3YW50ZWRfY29kZSkKICAgIHsKICAgICAgaWYgKGxfY29uc3QgJiYgaW50ZWdlcl96ZXJvcCAobF9jb25zdCkgJiYgaW50ZWdlcl9wb3cycCAobGxfbWFzaykpCgl7CgkgIC8qIE1ha2UgdGhlIGxlZnQgb3BlcmFuZCB1bnNpZ25lZCwgc2luY2Ugd2UgYXJlIG9ubHkgaW50ZXJlc3RlZAoJICAgICBpbiB0aGUgdmFsdWUgb2Ygb25lIGJpdC4gIE90aGVyd2lzZSB3ZSBhcmUgZG9pbmcgdGhlIHdyb25nCgkgICAgIHRoaW5nIGJlbG93LiAgKi8KCSAgbGxfdW5zaWduZWRwID0gMTsKCSAgbF9jb25zdCA9IGxsX21hc2s7Cgl9CiAgICAgIGVsc2UKCXJldHVybiAwOwogICAgfQoKICAvKiBUaGlzIGlzIGFuYWxvZ291cyB0byB0aGUgY29kZSBmb3IgbF9jb25zdCBhYm92ZS4gICovCiAgaWYgKHJjb2RlICE9IHdhbnRlZF9jb2RlKQogICAgewogICAgICBpZiAocl9jb25zdCAmJiBpbnRlZ2VyX3plcm9wIChyX2NvbnN0KSAmJiBpbnRlZ2VyX3BvdzJwIChybF9tYXNrKSkKCXsKCSAgcmxfdW5zaWduZWRwID0gMTsKCSAgcl9jb25zdCA9IHJsX21hc2s7Cgl9CiAgICAgIGVsc2UKCXJldHVybiAwOwogICAgfQoKICAvKiBBZnRlciB0aGlzIHBvaW50IGFsbCBvcHRpbWl6YXRpb25zIHdpbGwgZ2VuZXJhdGUgYml0LWZpZWxkCiAgICAgcmVmZXJlbmNlcywgd2hpY2ggd2UgbWlnaHQgbm90IHdhbnQuICAqLwogIGlmICghICgqbGFuZ19ob29rcy5jYW5fdXNlX2JpdF9maWVsZHNfcCkgKCkpCiAgICByZXR1cm4gMDsKCiAgLyogU2VlIGlmIHdlIGNhbiBmaW5kIGEgbW9kZSB0aGF0IGNvbnRhaW5zIGJvdGggZmllbGRzIGJlaW5nIGNvbXBhcmVkIG9uCiAgICAgdGhlIGxlZnQuICBJZiB3ZSBjYW4ndCwgZmFpbC4gIE90aGVyd2lzZSwgdXBkYXRlIGFsbCBjb25zdGFudHMgYW5kIG1hc2tzCiAgICAgdG8gYmUgcmVsYXRpdmUgdG8gYSBmaWVsZCBvZiB0aGF0IHNpemUuICAqLwogIGZpcnN0X2JpdCA9IE1JTiAobGxfYml0cG9zLCBybF9iaXRwb3MpOwogIGVuZF9iaXQgPSBNQVggKGxsX2JpdHBvcyArIGxsX2JpdHNpemUsIHJsX2JpdHBvcyArIHJsX2JpdHNpemUpOwogIGxubW9kZSA9IGdldF9iZXN0X21vZGUgKGVuZF9iaXQgLSBmaXJzdF9iaXQsIGZpcnN0X2JpdCwKCQkJICBUWVBFX0FMSUdOIChUUkVFX1RZUEUgKGxsX2lubmVyKSksIHdvcmRfbW9kZSwKCQkJICB2b2xhdGlsZXApOwogIGlmIChsbm1vZGUgPT0gVk9JRG1vZGUpCiAgICByZXR1cm4gMDsKCiAgbG5iaXRzaXplID0gR0VUX01PREVfQklUU0laRSAobG5tb2RlKTsKICBsbmJpdHBvcyA9IGZpcnN0X2JpdCAmIH4gKGxuYml0c2l6ZSAtIDEpOwogIGxudHlwZSA9ICgqbGFuZ19ob29rcy50eXBlcy50eXBlX2Zvcl9zaXplKSAobG5iaXRzaXplLCAxKTsKICB4bGxfYml0cG9zID0gbGxfYml0cG9zIC0gbG5iaXRwb3MsIHhybF9iaXRwb3MgPSBybF9iaXRwb3MgLSBsbmJpdHBvczsKCiAgaWYgKEJZVEVTX0JJR19FTkRJQU4pCiAgICB7CiAgICAgIHhsbF9iaXRwb3MgPSBsbmJpdHNpemUgLSB4bGxfYml0cG9zIC0gbGxfYml0c2l6ZTsKICAgICAgeHJsX2JpdHBvcyA9IGxuYml0c2l6ZSAtIHhybF9iaXRwb3MgLSBybF9iaXRzaXplOwogICAgfQoKICBsbF9tYXNrID0gY29uc3RfYmlub3AgKExTSElGVF9FWFBSLCBmb2xkX2NvbnZlcnQgKGxudHlwZSwgbGxfbWFzayksCgkJCSBzaXplX2ludCAoeGxsX2JpdHBvcyksIDApOwogIHJsX21hc2sgPSBjb25zdF9iaW5vcCAoTFNISUZUX0VYUFIsIGZvbGRfY29udmVydCAobG50eXBlLCBybF9tYXNrKSwKCQkJIHNpemVfaW50ICh4cmxfYml0cG9zKSwgMCk7CgogIGlmIChsX2NvbnN0KQogICAgewogICAgICBsX2NvbnN0ID0gZm9sZF9jb252ZXJ0IChsbnR5cGUsIGxfY29uc3QpOwogICAgICBsX2NvbnN0ID0gdW5leHRlbmQgKGxfY29uc3QsIGxsX2JpdHNpemUsIGxsX3Vuc2lnbmVkcCwgbGxfYW5kX21hc2spOwogICAgICBsX2NvbnN0ID0gY29uc3RfYmlub3AgKExTSElGVF9FWFBSLCBsX2NvbnN0LCBzaXplX2ludCAoeGxsX2JpdHBvcyksIDApOwogICAgICBpZiAoISBpbnRlZ2VyX3plcm9wIChjb25zdF9iaW5vcCAoQklUX0FORF9FWFBSLCBsX2NvbnN0LAoJCQkJCWZvbGQgKGJ1aWxkMSAoQklUX05PVF9FWFBSLAoJCQkJCQkgICAgICBsbnR5cGUsIGxsX21hc2spKSwKCQkJCQkwKSkpCgl7CgkgIHdhcm5pbmcgKCJjb21wYXJpc29uIGlzIGFsd2F5cyAlZCIsIHdhbnRlZF9jb2RlID09IE5FX0VYUFIpOwoKCSAgcmV0dXJuIGZvbGRfY29udmVydCAodHJ1dGhfdHlwZSwKCQkJICAgICAgIHdhbnRlZF9jb2RlID09IE5FX0VYUFIKCQkJICAgICAgID8gaW50ZWdlcl9vbmVfbm9kZSA6IGludGVnZXJfemVyb19ub2RlKTsKCX0KICAgIH0KICBpZiAocl9jb25zdCkKICAgIHsKICAgICAgcl9jb25zdCA9IGZvbGRfY29udmVydCAobG50eXBlLCByX2NvbnN0KTsKICAgICAgcl9jb25zdCA9IHVuZXh0ZW5kIChyX2NvbnN0LCBybF9iaXRzaXplLCBybF91bnNpZ25lZHAsIHJsX2FuZF9tYXNrKTsKICAgICAgcl9jb25zdCA9IGNvbnN0X2Jpbm9wIChMU0hJRlRfRVhQUiwgcl9jb25zdCwgc2l6ZV9pbnQgKHhybF9iaXRwb3MpLCAwKTsKICAgICAgaWYgKCEgaW50ZWdlcl96ZXJvcCAoY29uc3RfYmlub3AgKEJJVF9BTkRfRVhQUiwgcl9jb25zdCwKCQkJCQlmb2xkIChidWlsZDEgKEJJVF9OT1RfRVhQUiwKCQkJCQkJICAgICAgbG50eXBlLCBybF9tYXNrKSksCgkJCQkJMCkpKQoJewoJICB3YXJuaW5nICgiY29tcGFyaXNvbiBpcyBhbHdheXMgJWQiLCB3YW50ZWRfY29kZSA9PSBORV9FWFBSKTsKCgkgIHJldHVybiBmb2xkX2NvbnZlcnQgKHRydXRoX3R5cGUsCgkJCSAgICAgICB3YW50ZWRfY29kZSA9PSBORV9FWFBSCgkJCSAgICAgICA/IGludGVnZXJfb25lX25vZGUgOiBpbnRlZ2VyX3plcm9fbm9kZSk7Cgl9CiAgICB9CgogIC8qIElmIHRoZSByaWdodCBzaWRlcyBhcmUgbm90IGNvbnN0YW50LCBkbyB0aGUgc2FtZSBmb3IgaXQuICBBbHNvLAogICAgIGRpc2FsbG93IHRoaXMgb3B0aW1pemF0aW9uIGlmIGEgc2l6ZSBvciBzaWduZWRuZXNzIG1pc21hdGNoIG9jY3VycwogICAgIGJldHdlZW4gdGhlIGxlZnQgYW5kIHJpZ2h0IHNpZGVzLiAgKi8KICBpZiAobF9jb25zdCA9PSAwKQogICAgewogICAgICBpZiAobGxfYml0c2l6ZSAhPSBscl9iaXRzaXplIHx8IHJsX2JpdHNpemUgIT0gcnJfYml0c2l6ZQoJICB8fCBsbF91bnNpZ25lZHAgIT0gbHJfdW5zaWduZWRwIHx8IHJsX3Vuc2lnbmVkcCAhPSBycl91bnNpZ25lZHAKCSAgLyogTWFrZSBzdXJlIHRoZSB0d28gZmllbGRzIG9uIHRoZSByaWdodAoJICAgICBjb3JyZXNwb25kIHRvIHRoZSBsZWZ0IHdpdGhvdXQgYmVpbmcgc3dhcHBlZC4gICovCgkgIHx8IGxsX2JpdHBvcyAtIHJsX2JpdHBvcyAhPSBscl9iaXRwb3MgLSBycl9iaXRwb3MpCglyZXR1cm4gMDsKCiAgICAgIGZpcnN0X2JpdCA9IE1JTiAobHJfYml0cG9zLCBycl9iaXRwb3MpOwogICAgICBlbmRfYml0ID0gTUFYIChscl9iaXRwb3MgKyBscl9iaXRzaXplLCBycl9iaXRwb3MgKyBycl9iaXRzaXplKTsKICAgICAgcm5tb2RlID0gZ2V0X2Jlc3RfbW9kZSAoZW5kX2JpdCAtIGZpcnN0X2JpdCwgZmlyc3RfYml0LAoJCQkgICAgICBUWVBFX0FMSUdOIChUUkVFX1RZUEUgKGxyX2lubmVyKSksIHdvcmRfbW9kZSwKCQkJICAgICAgdm9sYXRpbGVwKTsKICAgICAgaWYgKHJubW9kZSA9PSBWT0lEbW9kZSkKCXJldHVybiAwOwoKICAgICAgcm5iaXRzaXplID0gR0VUX01PREVfQklUU0laRSAocm5tb2RlKTsKICAgICAgcm5iaXRwb3MgPSBmaXJzdF9iaXQgJiB+IChybmJpdHNpemUgLSAxKTsKICAgICAgcm50eXBlID0gKCpsYW5nX2hvb2tzLnR5cGVzLnR5cGVfZm9yX3NpemUpIChybmJpdHNpemUsIDEpOwogICAgICB4bHJfYml0cG9zID0gbHJfYml0cG9zIC0gcm5iaXRwb3MsIHhycl9iaXRwb3MgPSBycl9iaXRwb3MgLSBybmJpdHBvczsKCiAgICAgIGlmIChCWVRFU19CSUdfRU5ESUFOKQoJewoJICB4bHJfYml0cG9zID0gcm5iaXRzaXplIC0geGxyX2JpdHBvcyAtIGxyX2JpdHNpemU7CgkgIHhycl9iaXRwb3MgPSBybmJpdHNpemUgLSB4cnJfYml0cG9zIC0gcnJfYml0c2l6ZTsKCX0KCiAgICAgIGxyX21hc2sgPSBjb25zdF9iaW5vcCAoTFNISUZUX0VYUFIsIGZvbGRfY29udmVydCAocm50eXBlLCBscl9tYXNrKSwKCQkJICAgICBzaXplX2ludCAoeGxyX2JpdHBvcyksIDApOwogICAgICBycl9tYXNrID0gY29uc3RfYmlub3AgKExTSElGVF9FWFBSLCBmb2xkX2NvbnZlcnQgKHJudHlwZSwgcnJfbWFzayksCgkJCSAgICAgc2l6ZV9pbnQgKHhycl9iaXRwb3MpLCAwKTsKCiAgICAgIC8qIE1ha2UgYSBtYXNrIHRoYXQgY29ycmVzcG9uZHMgdG8gYm90aCBmaWVsZHMgYmVpbmcgY29tcGFyZWQuCgkgRG8gdGhpcyBmb3IgYm90aCBpdGVtcyBiZWluZyBjb21wYXJlZC4gIElmIHRoZSBvcGVyYW5kcyBhcmUgdGhlCgkgc2FtZSBzaXplIGFuZCB0aGUgYml0cyBiZWluZyBjb21wYXJlZCBhcmUgaW4gdGhlIHNhbWUgcG9zaXRpb24KCSB0aGVuIHdlIGNhbiBkbyB0aGlzIGJ5IG1hc2tpbmcgYm90aCBhbmQgY29tcGFyaW5nIHRoZSBtYXNrZWQKCSByZXN1bHRzLiAgKi8KICAgICAgbGxfbWFzayA9IGNvbnN0X2Jpbm9wIChCSVRfSU9SX0VYUFIsIGxsX21hc2ssIHJsX21hc2ssIDApOwogICAgICBscl9tYXNrID0gY29uc3RfYmlub3AgKEJJVF9JT1JfRVhQUiwgbHJfbWFzaywgcnJfbWFzaywgMCk7CiAgICAgIGlmIChsbmJpdHNpemUgPT0gcm5iaXRzaXplICYmIHhsbF9iaXRwb3MgPT0geGxyX2JpdHBvcykKCXsKCSAgbGhzID0gbWFrZV9iaXRfZmllbGRfcmVmIChsbF9pbm5lciwgbG50eXBlLCBsbmJpdHNpemUsIGxuYml0cG9zLAoJCQkJICAgIGxsX3Vuc2lnbmVkcCB8fCBybF91bnNpZ25lZHApOwoJICBpZiAoISBhbGxfb25lc19tYXNrX3AgKGxsX21hc2ssIGxuYml0c2l6ZSkpCgkgICAgbGhzID0gYnVpbGQgKEJJVF9BTkRfRVhQUiwgbG50eXBlLCBsaHMsIGxsX21hc2spOwoKCSAgcmhzID0gbWFrZV9iaXRfZmllbGRfcmVmIChscl9pbm5lciwgcm50eXBlLCBybmJpdHNpemUsIHJuYml0cG9zLAoJCQkJICAgIGxyX3Vuc2lnbmVkcCB8fCBycl91bnNpZ25lZHApOwoJICBpZiAoISBhbGxfb25lc19tYXNrX3AgKGxyX21hc2ssIHJuYml0c2l6ZSkpCgkgICAgcmhzID0gYnVpbGQgKEJJVF9BTkRfRVhQUiwgcm50eXBlLCByaHMsIGxyX21hc2spOwoKCSAgcmV0dXJuIGJ1aWxkICh3YW50ZWRfY29kZSwgdHJ1dGhfdHlwZSwgbGhzLCByaHMpOwoJfQoKICAgICAgLyogVGhlcmUgaXMgc3RpbGwgYW5vdGhlciB3YXkgd2UgY2FuIGRvIHNvbWV0aGluZzogIElmIGJvdGggcGFpcnMgb2YKCSBmaWVsZHMgYmVpbmcgY29tcGFyZWQgYXJlIGFkamFjZW50LCB3ZSBtYXkgYmUgYWJsZSB0byBtYWtlIGEgd2lkZXIKCSBmaWVsZCBjb250YWluaW5nIHRoZW0gYm90aC4KCgkgTm90ZSB0aGF0IHdlIHN0aWxsIG11c3QgbWFzayB0aGUgbGhzL3JocyBleHByZXNzaW9ucy4gIEZ1cnRoZXJtb3JlLAoJIHRoZSBtYXNrIG11c3QgYmUgc2hpZnRlZCB0byBhY2NvdW50IGZvciB0aGUgc2hpZnQgZG9uZSBieQoJIG1ha2VfYml0X2ZpZWxkX3JlZi4gICovCiAgICAgIGlmICgobGxfYml0c2l6ZSArIGxsX2JpdHBvcyA9PSBybF9iaXRwb3MKCSAgICYmIGxyX2JpdHNpemUgKyBscl9iaXRwb3MgPT0gcnJfYml0cG9zKQoJICB8fCAobGxfYml0cG9zID09IHJsX2JpdHBvcyArIHJsX2JpdHNpemUKCSAgICAgICYmIGxyX2JpdHBvcyA9PSBycl9iaXRwb3MgKyBycl9iaXRzaXplKSkKCXsKCSAgdHJlZSB0eXBlOwoKCSAgbGhzID0gbWFrZV9iaXRfZmllbGRfcmVmIChsbF9pbm5lciwgbG50eXBlLCBsbF9iaXRzaXplICsgcmxfYml0c2l6ZSwKCQkJCSAgICBNSU4gKGxsX2JpdHBvcywgcmxfYml0cG9zKSwgbGxfdW5zaWduZWRwKTsKCSAgcmhzID0gbWFrZV9iaXRfZmllbGRfcmVmIChscl9pbm5lciwgcm50eXBlLCBscl9iaXRzaXplICsgcnJfYml0c2l6ZSwKCQkJCSAgICBNSU4gKGxyX2JpdHBvcywgcnJfYml0cG9zKSwgbHJfdW5zaWduZWRwKTsKCgkgIGxsX21hc2sgPSBjb25zdF9iaW5vcCAoUlNISUZUX0VYUFIsIGxsX21hc2ssCgkJCQkgc2l6ZV9pbnQgKE1JTiAoeGxsX2JpdHBvcywgeHJsX2JpdHBvcykpLCAwKTsKCSAgbHJfbWFzayA9IGNvbnN0X2Jpbm9wIChSU0hJRlRfRVhQUiwgbHJfbWFzaywKCQkJCSBzaXplX2ludCAoTUlOICh4bHJfYml0cG9zLCB4cnJfYml0cG9zKSksIDApOwoKCSAgLyogQ29udmVydCB0byB0aGUgc21hbGxlciB0eXBlIGJlZm9yZSBtYXNraW5nIG91dCB1bndhbnRlZCBiaXRzLiAgKi8KCSAgdHlwZSA9IGxudHlwZTsKCSAgaWYgKGxudHlwZSAhPSBybnR5cGUpCgkgICAgewoJICAgICAgaWYgKGxuYml0c2l6ZSA+IHJuYml0c2l6ZSkKCQl7CgkJICBsaHMgPSBmb2xkX2NvbnZlcnQgKHJudHlwZSwgbGhzKTsKCQkgIGxsX21hc2sgPSBmb2xkX2NvbnZlcnQgKHJudHlwZSwgbGxfbWFzayk7CgkJICB0eXBlID0gcm50eXBlOwoJCX0KCSAgICAgIGVsc2UgaWYgKGxuYml0c2l6ZSA8IHJuYml0c2l6ZSkKCQl7CgkJICByaHMgPSBmb2xkX2NvbnZlcnQgKGxudHlwZSwgcmhzKTsKCQkgIGxyX21hc2sgPSBmb2xkX2NvbnZlcnQgKGxudHlwZSwgbHJfbWFzayk7CgkJICB0eXBlID0gbG50eXBlOwoJCX0KCSAgICB9CgoJICBpZiAoISBhbGxfb25lc19tYXNrX3AgKGxsX21hc2ssIGxsX2JpdHNpemUgKyBybF9iaXRzaXplKSkKCSAgICBsaHMgPSBidWlsZCAoQklUX0FORF9FWFBSLCB0eXBlLCBsaHMsIGxsX21hc2spOwoKCSAgaWYgKCEgYWxsX29uZXNfbWFza19wIChscl9tYXNrLCBscl9iaXRzaXplICsgcnJfYml0c2l6ZSkpCgkgICAgcmhzID0gYnVpbGQgKEJJVF9BTkRfRVhQUiwgdHlwZSwgcmhzLCBscl9tYXNrKTsKCgkgIHJldHVybiBidWlsZCAod2FudGVkX2NvZGUsIHRydXRoX3R5cGUsIGxocywgcmhzKTsKCX0KCiAgICAgIHJldHVybiAwOwogICAgfQoKICAvKiBIYW5kbGUgdGhlIGNhc2Ugb2YgY29tcGFyaXNvbnMgd2l0aCBjb25zdGFudHMuICBJZiB0aGVyZSBpcyBzb21ldGhpbmcgaW4KICAgICBjb21tb24gYmV0d2VlbiB0aGUgbWFza3MsIHRob3NlIGJpdHMgb2YgdGhlIGNvbnN0YW50cyBtdXN0IGJlIHRoZSBzYW1lLgogICAgIElmIG5vdCwgdGhlIGNvbmRpdGlvbiBpcyBhbHdheXMgZmFsc2UuICBUZXN0IGZvciB0aGlzIHRvIGF2b2lkIGdlbmVyYXRpbmcKICAgICBpbmNvcnJlY3QgY29kZSBiZWxvdy4gICovCiAgcmVzdWx0ID0gY29uc3RfYmlub3AgKEJJVF9BTkRfRVhQUiwgbGxfbWFzaywgcmxfbWFzaywgMCk7CiAgaWYgKCEgaW50ZWdlcl96ZXJvcCAocmVzdWx0KQogICAgICAmJiBzaW1wbGVfY3N0X2VxdWFsIChjb25zdF9iaW5vcCAoQklUX0FORF9FWFBSLCByZXN1bHQsIGxfY29uc3QsIDApLAoJCQkgICBjb25zdF9iaW5vcCAoQklUX0FORF9FWFBSLCByZXN1bHQsIHJfY29uc3QsIDApKSAhPSAxKQogICAgewogICAgICBpZiAod2FudGVkX2NvZGUgPT0gTkVfRVhQUikKCXsKCSAgd2FybmluZyAoImBvcicgb2YgdW5tYXRjaGVkIG5vdC1lcXVhbCB0ZXN0cyBpcyBhbHdheXMgMSIpOwoJICByZXR1cm4gZm9sZF9jb252ZXJ0ICh0cnV0aF90eXBlLCBpbnRlZ2VyX29uZV9ub2RlKTsKCX0KICAgICAgZWxzZQoJewoJICB3YXJuaW5nICgiYGFuZCcgb2YgbXV0dWFsbHkgZXhjbHVzaXZlIGVxdWFsLXRlc3RzIGlzIGFsd2F5cyAwIik7CgkgIHJldHVybiBmb2xkX2NvbnZlcnQgKHRydXRoX3R5cGUsIGludGVnZXJfemVyb19ub2RlKTsKCX0KICAgIH0KCiAgLyogQ29uc3RydWN0IHRoZSBleHByZXNzaW9uIHdlIHdpbGwgcmV0dXJuLiAgRmlyc3QgZ2V0IHRoZSBjb21wb25lbnQKICAgICByZWZlcmVuY2Ugd2Ugd2lsbCBtYWtlLiAgVW5sZXNzIHRoZSBtYXNrIGlzIGFsbCBvbmVzIHRoZSB3aWR0aCBvZgogICAgIHRoYXQgZmllbGQsIHBlcmZvcm0gdGhlIG1hc2sgb3BlcmF0aW9uLiAgVGhlbiBjb21wYXJlIHdpdGggdGhlCiAgICAgbWVyZ2VkIGNvbnN0YW50LiAgKi8KICByZXN1bHQgPSBtYWtlX2JpdF9maWVsZF9yZWYgKGxsX2lubmVyLCBsbnR5cGUsIGxuYml0c2l6ZSwgbG5iaXRwb3MsCgkJCSAgICAgICBsbF91bnNpZ25lZHAgfHwgcmxfdW5zaWduZWRwKTsKCiAgbGxfbWFzayA9IGNvbnN0X2Jpbm9wIChCSVRfSU9SX0VYUFIsIGxsX21hc2ssIHJsX21hc2ssIDApOwogIGlmICghIGFsbF9vbmVzX21hc2tfcCAobGxfbWFzaywgbG5iaXRzaXplKSkKICAgIHJlc3VsdCA9IGJ1aWxkIChCSVRfQU5EX0VYUFIsIGxudHlwZSwgcmVzdWx0LCBsbF9tYXNrKTsKCiAgcmV0dXJuIGJ1aWxkICh3YW50ZWRfY29kZSwgdHJ1dGhfdHlwZSwgcmVzdWx0LAoJCWNvbnN0X2Jpbm9wIChCSVRfSU9SX0VYUFIsIGxfY29uc3QsIHJfY29uc3QsIDApKTsKfQoMCi8qIE9wdGltaXplIFQsIHdoaWNoIGlzIGEgY29tcGFyaXNvbiBvZiBhIE1JTl9FWFBSIG9yIE1BWF9FWFBSIHdpdGggYQogICBjb25zdGFudC4gICovCgpzdGF0aWMgdHJlZQpvcHRpbWl6ZV9taW5tYXhfY29tcGFyaXNvbiAodHJlZSB0KQp7CiAgdHJlZSB0eXBlID0gVFJFRV9UWVBFICh0KTsKICB0cmVlIGFyZzAgPSBUUkVFX09QRVJBTkQgKHQsIDApOwogIGVudW0gdHJlZV9jb2RlIG9wX2NvZGU7CiAgdHJlZSBjb21wX2NvbnN0ID0gVFJFRV9PUEVSQU5EICh0LCAxKTsKICB0cmVlIG1pbm1heF9jb25zdDsKICBpbnQgY29uc3RzX2VxdWFsLCBjb25zdHNfbHQ7CiAgdHJlZSBpbm5lcjsKCiAgU1RSSVBfU0lHTl9OT1BTIChhcmcwKTsKCiAgb3BfY29kZSA9IFRSRUVfQ09ERSAoYXJnMCk7CiAgbWlubWF4X2NvbnN0ID0gVFJFRV9PUEVSQU5EIChhcmcwLCAxKTsKICBjb25zdHNfZXF1YWwgPSB0cmVlX2ludF9jc3RfZXF1YWwgKG1pbm1heF9jb25zdCwgY29tcF9jb25zdCk7CiAgY29uc3RzX2x0ID0gdHJlZV9pbnRfY3N0X2x0IChtaW5tYXhfY29uc3QsIGNvbXBfY29uc3QpOwogIGlubmVyID0gVFJFRV9PUEVSQU5EIChhcmcwLCAwKTsKCiAgLyogSWYgc29tZXRoaW5nIGRvZXMgbm90IHBlcm1pdCB1cyB0byBvcHRpbWl6ZSwgcmV0dXJuIHRoZSBvcmlnaW5hbCB0cmVlLiAgKi8KICBpZiAoKG9wX2NvZGUgIT0gTUlOX0VYUFIgJiYgb3BfY29kZSAhPSBNQVhfRVhQUikKICAgICAgfHwgVFJFRV9DT0RFIChjb21wX2NvbnN0KSAhPSBJTlRFR0VSX0NTVAogICAgICB8fCBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChjb21wX2NvbnN0KQogICAgICB8fCBUUkVFX0NPREUgKG1pbm1heF9jb25zdCkgIT0gSU5URUdFUl9DU1QKICAgICAgfHwgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAobWlubWF4X2NvbnN0KSkKICAgIHJldHVybiB0OwoKICAvKiBOb3cgaGFuZGxlIGFsbCB0aGUgdmFyaW91cyBjb21wYXJpc29uIGNvZGVzLiAgV2Ugb25seSBoYW5kbGUgRVFfRVhQUgogICAgIGFuZCBHVF9FWFBSLCBkb2luZyB0aGUgcmVzdCB3aXRoIHJlY3Vyc2l2ZSBjYWxscyB1c2luZyBsb2dpY2FsCiAgICAgc2ltcGxpZmljYXRpb25zLiAgKi8KICBzd2l0Y2ggKFRSRUVfQ09ERSAodCkpCiAgICB7CiAgICBjYXNlIE5FX0VYUFI6ICBjYXNlIExUX0VYUFI6ICBjYXNlIExFX0VYUFI6CiAgICAgIHJldHVybgoJaW52ZXJ0X3RydXRodmFsdWUgKG9wdGltaXplX21pbm1heF9jb21wYXJpc29uIChpbnZlcnRfdHJ1dGh2YWx1ZSAodCkpKTsKCiAgICBjYXNlIEdFX0VYUFI6CiAgICAgIHJldHVybgoJZm9sZCAoYnVpbGQgKFRSVVRIX09SSUZfRVhQUiwgdHlwZSwKCQkgICAgIG9wdGltaXplX21pbm1heF9jb21wYXJpc29uCgkJICAgICAoYnVpbGQgKEVRX0VYUFIsIHR5cGUsIGFyZzAsIGNvbXBfY29uc3QpKSwKCQkgICAgIG9wdGltaXplX21pbm1heF9jb21wYXJpc29uCgkJICAgICAoYnVpbGQgKEdUX0VYUFIsIHR5cGUsIGFyZzAsIGNvbXBfY29uc3QpKSkpOwoKICAgIGNhc2UgRVFfRVhQUjoKICAgICAgaWYgKG9wX2NvZGUgPT0gTUFYX0VYUFIgJiYgY29uc3RzX2VxdWFsKQoJLyogTUFYIChYLCAwKSA9PSAwICAtPiAgWCA8PSAwICAqLwoJcmV0dXJuIGZvbGQgKGJ1aWxkIChMRV9FWFBSLCB0eXBlLCBpbm5lciwgY29tcF9jb25zdCkpOwoKICAgICAgZWxzZSBpZiAob3BfY29kZSA9PSBNQVhfRVhQUiAmJiBjb25zdHNfbHQpCgkvKiBNQVggKFgsIDApID09IDUgIC0+ICBYID09IDUgICAqLwoJcmV0dXJuIGZvbGQgKGJ1aWxkIChFUV9FWFBSLCB0eXBlLCBpbm5lciwgY29tcF9jb25zdCkpOwoKICAgICAgZWxzZSBpZiAob3BfY29kZSA9PSBNQVhfRVhQUikKCS8qIE1BWCAoWCwgMCkgPT0gLTEgIC0+ICBmYWxzZSAgKi8KCXJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSwgaW5uZXIpOwoKICAgICAgZWxzZSBpZiAoY29uc3RzX2VxdWFsKQoJLyogTUlOIChYLCAwKSA9PSAwICAtPiAgWCA+PSAwICAqLwoJcmV0dXJuIGZvbGQgKGJ1aWxkIChHRV9FWFBSLCB0eXBlLCBpbm5lciwgY29tcF9jb25zdCkpOwoKICAgICAgZWxzZSBpZiAoY29uc3RzX2x0KQoJLyogTUlOIChYLCAwKSA9PSA1ICAtPiAgZmFsc2UgICovCglyZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgaW50ZWdlcl96ZXJvX25vZGUsIGlubmVyKTsKCiAgICAgIGVsc2UKCS8qIE1JTiAoWCwgMCkgPT0gLTEgIC0+ICBYID09IC0xICAqLwoJcmV0dXJuIGZvbGQgKGJ1aWxkIChFUV9FWFBSLCB0eXBlLCBpbm5lciwgY29tcF9jb25zdCkpOwoKICAgIGNhc2UgR1RfRVhQUjoKICAgICAgaWYgKG9wX2NvZGUgPT0gTUFYX0VYUFIgJiYgKGNvbnN0c19lcXVhbCB8fCBjb25zdHNfbHQpKQoJLyogTUFYIChYLCAwKSA+IDAgIC0+ICBYID4gMAoJICAgTUFYIChYLCAwKSA+IDUgIC0+ICBYID4gNSAgKi8KCXJldHVybiBmb2xkIChidWlsZCAoR1RfRVhQUiwgdHlwZSwgaW5uZXIsIGNvbXBfY29uc3QpKTsKCiAgICAgIGVsc2UgaWYgKG9wX2NvZGUgPT0gTUFYX0VYUFIpCgkvKiBNQVggKFgsIDApID4gLTEgIC0+ICB0cnVlICAqLwoJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIGludGVnZXJfb25lX25vZGUsIGlubmVyKTsKCiAgICAgIGVsc2UgaWYgKG9wX2NvZGUgPT0gTUlOX0VYUFIgJiYgKGNvbnN0c19lcXVhbCB8fCBjb25zdHNfbHQpKQoJLyogTUlOIChYLCAwKSA+IDAgIC0+ICBmYWxzZQoJICAgTUlOIChYLCAwKSA+IDUgIC0+ICBmYWxzZSAgKi8KCXJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSwgaW5uZXIpOwoKICAgICAgZWxzZQoJLyogTUlOIChYLCAwKSA+IC0xICAtPiAgWCA+IC0xICAqLwoJcmV0dXJuIGZvbGQgKGJ1aWxkIChHVF9FWFBSLCB0eXBlLCBpbm5lciwgY29tcF9jb25zdCkpOwoKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiB0OwogICAgfQp9CgwKLyogVCBpcyBhbiBpbnRlZ2VyIGV4cHJlc3Npb24gdGhhdCBpcyBiZWluZyBtdWx0aXBsaWVkLCBkaXZpZGVkLCBvciB0YWtlbiBhCiAgIG1vZHVsdXMgKENPREUgc2F5cyB3aGljaCBhbmQgd2hhdCBraW5kIG9mIGRpdmlkZSBvciBtb2R1bHVzKSBieSBhCiAgIGNvbnN0YW50IEMuICBTZWUgaWYgd2UgY2FuIGVsaW1pbmF0ZSB0aGF0IG9wZXJhdGlvbiBieSBmb2xkaW5nIGl0IHdpdGgKICAgb3RoZXIgb3BlcmF0aW9ucyBhbHJlYWR5IGluIFQuICBXSURFX1RZUEUsIGlmIG5vbi1udWxsLCBpcyBhIHR5cGUgdGhhdAogICBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIGNvbXB1dGF0aW9uIGlmIHdpZGVyIHRoYW4gb3VyIHR5cGUuCgogICBGb3IgZXhhbXBsZSwgaWYgd2UgYXJlIGRpdmlkaW5nIChYICogOCkgKyAoWSAqIDE2KSBieSA0LCB3ZSBjYW4gcmV0dXJuCiAgIChYICogMikgKyAoWSAqIDQpLiAgV2UgbXVzdCwgaG93ZXZlciwgYmUgYXNzdXJlZCB0aGF0IGVpdGhlciB0aGUgb3JpZ2luYWwKICAgZXhwcmVzc2lvbiB3b3VsZCBub3Qgb3ZlcmZsb3cgb3IgdGhhdCBvdmVyZmxvdyBpcyB1bmRlZmluZWQgZm9yIHRoZSB0eXBlCiAgIGluIHRoZSBsYW5ndWFnZSBpbiBxdWVzdGlvbi4KCiAgIFdlIGFsc28gY2Fub25pY2FsaXplIChYICsgNykgKiA0IGludG8gWCAqIDQgKyAyOCBpbiB0aGUgaG9wZSB0aGF0IGVpdGhlcgogICB0aGUgbWFjaGluZSBoYXMgYSBtdWx0aXBseS1hY2N1bXVsYXRlIGluc24gb3IgdGhhdCB0aGlzIGlzIHBhcnQgb2YgYW4KICAgYWRkcmVzc2luZyBjYWxjdWxhdGlvbi4KCiAgIElmIHdlIHJldHVybiBhIG5vbi1udWxsIGV4cHJlc3Npb24sIGl0IGlzIGFuIGVxdWl2YWxlbnQgZm9ybSBvZiB0aGUKICAgb3JpZ2luYWwgY29tcHV0YXRpb24sIGJ1dCBuZWVkIG5vdCBiZSBpbiB0aGUgb3JpZ2luYWwgdHlwZS4gICovCgpzdGF0aWMgdHJlZQpleHRyYWN0X211bGRpdiAodHJlZSB0LCB0cmVlIGMsIGVudW0gdHJlZV9jb2RlIGNvZGUsIHRyZWUgd2lkZV90eXBlKQp7CiAgLyogVG8gYXZvaWQgZXhwb25lbnRpYWwgc2VhcmNoIGRlcHRoLCByZWZ1c2UgdG8gYWxsb3cgcmVjdXJzaW9uIHBhc3QKICAgICB0aHJlZSBsZXZlbHMuICBCZXlvbmQgdGhhdCAoMSkgaXQncyBoaWdobHkgdW5saWtlbHkgdGhhdCB3ZSdsbCBmaW5kCiAgICAgc29tZXRoaW5nIGludGVyZXN0aW5nIGFuZCAoMikgd2UndmUgcHJvYmFibHkgcHJvY2Vzc2VkIGl0IGJlZm9yZQogICAgIHdoZW4gd2UgYnVpbHQgdGhlIGlubmVyIGV4cHJlc3Npb24uICAqLwoKICBzdGF0aWMgaW50IGRlcHRoOwogIHRyZWUgcmV0OwoKICBpZiAoZGVwdGggPiAzKQogICAgcmV0dXJuIE5VTEw7CgogIGRlcHRoKys7CiAgcmV0ID0gZXh0cmFjdF9tdWxkaXZfMSAodCwgYywgY29kZSwgd2lkZV90eXBlKTsKICBkZXB0aC0tOwoKICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgdHJlZQpleHRyYWN0X211bGRpdl8xICh0cmVlIHQsIHRyZWUgYywgZW51bSB0cmVlX2NvZGUgY29kZSwgdHJlZSB3aWRlX3R5cGUpCnsKICB0cmVlIHR5cGUgPSBUUkVFX1RZUEUgKHQpOwogIGVudW0gdHJlZV9jb2RlIHRjb2RlID0gVFJFRV9DT0RFICh0KTsKICB0cmVlIGN0eXBlID0gKHdpZGVfdHlwZSAhPSAwICYmIChHRVRfTU9ERV9TSVpFIChUWVBFX01PREUgKHdpZGVfdHlwZSkpCgkJCQkgICA+IEdFVF9NT0RFX1NJWkUgKFRZUEVfTU9ERSAodHlwZSkpKQoJCT8gd2lkZV90eXBlIDogdHlwZSk7CiAgdHJlZSB0MSwgdDI7CiAgaW50IHNhbWVfcCA9IHRjb2RlID09IGNvZGU7CiAgdHJlZSBvcDAgPSBOVUxMX1RSRUUsIG9wMSA9IE5VTExfVFJFRTsKCiAgLyogRG9uJ3QgZGVhbCB3aXRoIGNvbnN0YW50cyBvZiB6ZXJvIGhlcmU7IHRoZXkgY29uZnVzZSB0aGUgY29kZSBiZWxvdy4gICovCiAgaWYgKGludGVnZXJfemVyb3AgKGMpKQogICAgcmV0dXJuIE5VTExfVFJFRTsKCiAgaWYgKFRSRUVfQ09ERV9DTEFTUyAodGNvZGUpID09ICcxJykKICAgIG9wMCA9IFRSRUVfT1BFUkFORCAodCwgMCk7CgogIGlmIChUUkVFX0NPREVfQ0xBU1MgKHRjb2RlKSA9PSAnMicpCiAgICBvcDAgPSBUUkVFX09QRVJBTkQgKHQsIDApLCBvcDEgPSBUUkVFX09QRVJBTkQgKHQsIDEpOwoKICAvKiBOb3RlIHRoYXQgd2UgbmVlZCBub3QgaGFuZGxlIGNvbmRpdGlvbmFsIG9wZXJhdGlvbnMgaGVyZSBzaW5jZSBmb2xkCiAgICAgYWxyZWFkeSBoYW5kbGVzIHRob3NlIGNhc2VzLiAgU28ganVzdCBkbyBhcml0aG1ldGljIGhlcmUuICAqLwogIHN3aXRjaCAodGNvZGUpCiAgICB7CiAgICBjYXNlIElOVEVHRVJfQ1NUOgogICAgICAvKiBGb3IgYSBjb25zdGFudCwgd2UgY2FuIGFsd2F5cyBzaW1wbGlmeSBpZiB3ZSBhcmUgYSBtdWx0aXBseQoJIG9yIChmb3IgZGl2aWRlIGFuZCBtb2R1bHVzKSBpZiBpdCBpcyBhIG11bHRpcGxlIG9mIG91ciBjb25zdGFudC4gICovCiAgICAgIGlmIChjb2RlID09IE1VTFRfRVhQUgoJICB8fCBpbnRlZ2VyX3plcm9wIChjb25zdF9iaW5vcCAoVFJVTkNfTU9EX0VYUFIsIHQsIGMsIDApKSkKCXJldHVybiBjb25zdF9iaW5vcCAoY29kZSwgZm9sZF9jb252ZXJ0IChjdHlwZSwgdCksCgkJCSAgICBmb2xkX2NvbnZlcnQgKGN0eXBlLCBjKSwgMCk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ09OVkVSVF9FWFBSOiAgY2FzZSBOT05fTFZBTFVFX0VYUFI6ICBjYXNlIE5PUF9FWFBSOgogICAgICAvKiBJZiBvcDAgaXMgYW4gZXhwcmVzc2lvbiAuLi4gICovCiAgICAgIGlmICgoVFJFRV9DT0RFX0NMQVNTIChUUkVFX0NPREUgKG9wMCkpID09ICc8JwoJICAgfHwgVFJFRV9DT0RFX0NMQVNTIChUUkVFX0NPREUgKG9wMCkpID09ICcxJwoJICAgfHwgVFJFRV9DT0RFX0NMQVNTIChUUkVFX0NPREUgKG9wMCkpID09ICcyJwoJICAgfHwgVFJFRV9DT0RFX0NMQVNTIChUUkVFX0NPREUgKG9wMCkpID09ICdlJykKCSAgLyogLi4uIGFuZCBpcyB1bnNpZ25lZCwgYW5kIGl0cyB0eXBlIGlzIHNtYWxsZXIgdGhhbiBjdHlwZSwKCSAgICAgdGhlbiB3ZSBjYW5ub3QgcGFzcyB0aHJvdWdoIGFzIHdpZGVuaW5nLiAgKi8KCSAgJiYgKChUUkVFX1VOU0lHTkVEIChUUkVFX1RZUEUgKG9wMCkpCgkgICAgICAgJiYgISAoVFJFRV9DT0RFIChUUkVFX1RZUEUgKG9wMCkpID09IElOVEVHRVJfVFlQRQoJCSAgICAgJiYgVFlQRV9JU19TSVpFVFlQRSAoVFJFRV9UWVBFIChvcDApKSkKCSAgICAgICAmJiAoR0VUX01PREVfU0laRSAoVFlQRV9NT0RFIChjdHlwZSkpCgkgICAgICAgICAgID4gR0VUX01PREVfU0laRSAoVFlQRV9NT0RFIChUUkVFX1RZUEUgKG9wMCkpKSkpCgkgICAgICAvKiAuLi4gb3IgdGhpcyBpcyBhIHRydW5jYXRpb24gKHQgaXMgbmFycm93ZXIgdGhhbiBvcDApLAoJCSB0aGVuIHdlIGNhbm5vdCBwYXNzIHRocm91Z2ggdGhpcyBuYXJyb3dpbmcuICAqLwoJICAgICAgfHwgKEdFVF9NT0RFX1NJWkUgKFRZUEVfTU9ERSAodHlwZSkpCgkJICA8IEdFVF9NT0RFX1NJWkUgKFRZUEVfTU9ERSAoVFJFRV9UWVBFIChvcDApKSkpCgkgICAgICAvKiAuLi4gb3Igc2lnbmVkbmVzcyBjaGFuZ2VzIGZvciBkaXZpc2lvbiBvciBtb2R1bHVzLAoJCSB0aGVuIHdlIGNhbm5vdCBwYXNzIHRocm91Z2ggdGhpcyBjb252ZXJzaW9uLiAgKi8KCSAgICAgIHx8IChjb2RlICE9IE1VTFRfRVhQUgoJCSAgJiYgKFRSRUVfVU5TSUdORUQgKGN0eXBlKQoJCSAgICAgICE9IFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAob3AwKSkpKSkpCglicmVhazsKCiAgICAgIC8qIFBhc3MgdGhlIGNvbnN0YW50IGRvd24gYW5kIHNlZSBpZiB3ZSBjYW4gbWFrZSBhIHNpbXBsaWZpY2F0aW9uLiAgSWYKCSB3ZSBjYW4sIHJlcGxhY2UgdGhpcyBleHByZXNzaW9uIHdpdGggdGhlIGlubmVyIHNpbXBsaWZpY2F0aW9uIGZvcgoJIHBvc3NpYmxlIGxhdGVyIGNvbnZlcnNpb24gdG8gb3VyIG9yIHNvbWUgb3RoZXIgdHlwZS4gICovCiAgICAgIGlmICgodDIgPSBmb2xkX2NvbnZlcnQgKFRSRUVfVFlQRSAob3AwKSwgYykpICE9IDAKCSAgJiYgVFJFRV9DT0RFICh0MikgPT0gSU5URUdFUl9DU1QKCSAgJiYgISBUUkVFX0NPTlNUQU5UX09WRVJGTE9XICh0MikKCSAgJiYgKDAgIT0gKHQxID0gZXh0cmFjdF9tdWxkaXYgKG9wMCwgdDIsIGNvZGUsCgkJCQkJIGNvZGUgPT0gTVVMVF9FWFBSCgkJCQkJID8gY3R5cGUgOiBOVUxMX1RSRUUpKSkpCglyZXR1cm4gdDE7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgTkVHQVRFX0VYUFI6ICBjYXNlIEFCU19FWFBSOgogICAgICBpZiAoKHQxID0gZXh0cmFjdF9tdWxkaXYgKG9wMCwgYywgY29kZSwgd2lkZV90eXBlKSkgIT0gMCkKCXJldHVybiBmb2xkIChidWlsZDEgKHRjb2RlLCBjdHlwZSwgZm9sZF9jb252ZXJ0IChjdHlwZSwgdDEpKSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgTUlOX0VYUFI6ICBjYXNlIE1BWF9FWFBSOgogICAgICAvKiBJZiB3aWRlbmluZyB0aGUgdHlwZSBjaGFuZ2VzIHRoZSBzaWduZWRuZXNzLCB0aGVuIHdlIGNhbid0IHBlcmZvcm0KCSB0aGlzIG9wdGltaXphdGlvbiBhcyB0aGF0IGNoYW5nZXMgdGhlIHJlc3VsdC4gICovCiAgICAgIGlmIChUUkVFX1VOU0lHTkVEIChjdHlwZSkgIT0gVFJFRV9VTlNJR05FRCAodHlwZSkpCglicmVhazsKCiAgICAgIC8qIE1JTiAoYSwgYikgLyA1IC0+IE1JTiAoYSAvIDUsIGIgLyA1KSAgKi8KICAgICAgaWYgKCh0MSA9IGV4dHJhY3RfbXVsZGl2IChvcDAsIGMsIGNvZGUsIHdpZGVfdHlwZSkpICE9IDAKCSAgJiYgKHQyID0gZXh0cmFjdF9tdWxkaXYgKG9wMSwgYywgY29kZSwgd2lkZV90eXBlKSkgIT0gMCkKCXsKCSAgaWYgKHRyZWVfaW50X2NzdF9zZ24gKGMpIDwgMCkKCSAgICB0Y29kZSA9ICh0Y29kZSA9PSBNSU5fRVhQUiA/IE1BWF9FWFBSIDogTUlOX0VYUFIpOwoKCSAgcmV0dXJuIGZvbGQgKGJ1aWxkICh0Y29kZSwgY3R5cGUsIGZvbGRfY29udmVydCAoY3R5cGUsIHQxKSwKCQkJICAgICAgZm9sZF9jb252ZXJ0IChjdHlwZSwgdDIpKSk7Cgl9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lUSF9SRUNPUkRfRVhQUjoKICAgICAgaWYgKCh0MSA9IGV4dHJhY3RfbXVsZGl2IChUUkVFX09QRVJBTkQgKHQsIDApLCBjLCBjb2RlLCB3aWRlX3R5cGUpKSAhPSAwKQoJcmV0dXJuIGJ1aWxkIChXSVRIX1JFQ09SRF9FWFBSLCBUUkVFX1RZUEUgKHQxKSwgdDEsCgkJICAgICAgVFJFRV9PUEVSQU5EICh0LCAxKSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgTFNISUZUX0VYUFI6ICBjYXNlIFJTSElGVF9FWFBSOgogICAgICAvKiBJZiB0aGUgc2Vjb25kIG9wZXJhbmQgaXMgY29uc3RhbnQsIHRoaXMgaXMgYSBtdWx0aXBsaWNhdGlvbgoJIG9yIGZsb29yIGRpdmlzaW9uLCBieSBhIHBvd2VyIG9mIHR3bywgc28gd2UgY2FuIHRyZWF0IGl0IHRoYXQKCSB3YXkgdW5sZXNzIHRoZSBtdWx0aXBsaWVyIG9yIGRpdmlzb3Igb3ZlcmZsb3dzLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAob3AxKSA9PSBJTlRFR0VSX0NTVAoJICAvKiBjb25zdF9iaW5vcCBtYXkgbm90IGRldGVjdCBvdmVyZmxvdyBjb3JyZWN0bHksCgkgICAgIHNvIGNoZWNrIGZvciBpdCBleHBsaWNpdGx5IGhlcmUuICAqLwoJICAmJiBUWVBFX1BSRUNJU0lPTiAoVFJFRV9UWVBFIChzaXplX29uZV9ub2RlKSkgPiBUUkVFX0lOVF9DU1RfTE9XIChvcDEpCgkgICYmIFRSRUVfSU5UX0NTVF9ISUdIIChvcDEpID09IDAKCSAgJiYgMCAhPSAodDEgPSBmb2xkX2NvbnZlcnQgKGN0eXBlLAoJCQkJICAgICAgY29uc3RfYmlub3AgKExTSElGVF9FWFBSLAoJCQkJCQkgICBzaXplX29uZV9ub2RlLAoJCQkJCQkgICBvcDEsIDApKSkKCSAgJiYgISBUUkVFX09WRVJGTE9XICh0MSkpCglyZXR1cm4gZXh0cmFjdF9tdWxkaXYgKGJ1aWxkICh0Y29kZSA9PSBMU0hJRlRfRVhQUgoJCQkJICAgICAgPyBNVUxUX0VYUFIgOiBGTE9PUl9ESVZfRVhQUiwKCQkJCSAgICAgIGN0eXBlLCBmb2xkX2NvbnZlcnQgKGN0eXBlLCBvcDApLCB0MSksCgkJCSAgICAgICBjLCBjb2RlLCB3aWRlX3R5cGUpOwogICAgICBicmVhazsKCiAgICBjYXNlIFBMVVNfRVhQUjogIGNhc2UgTUlOVVNfRVhQUjoKICAgICAgLyogU2VlIGlmIHdlIGNhbiBlbGltaW5hdGUgdGhlIG9wZXJhdGlvbiBvbiBib3RoIHNpZGVzLiAgSWYgd2UgY2FuLCB3ZQoJIGNhbiByZXR1cm4gYSBuZXcgUExVUyBvciBNSU5VUy4gIElmIHdlIGNhbid0LCB0aGUgb25seSByZW1haW5pbmcKCSBjYXNlcyB3aGVyZSB3ZSBjYW4gZG8gYW55dGhpbmcgYXJlIGlmIHRoZSBzZWNvbmQgb3BlcmFuZCBpcyBhCgkgY29uc3RhbnQuICAqLwogICAgICB0MSA9IGV4dHJhY3RfbXVsZGl2IChvcDAsIGMsIGNvZGUsIHdpZGVfdHlwZSk7CiAgICAgIHQyID0gZXh0cmFjdF9tdWxkaXYgKG9wMSwgYywgY29kZSwgd2lkZV90eXBlKTsKICAgICAgaWYgKHQxICE9IDAgJiYgdDIgIT0gMAoJICAmJiAoY29kZSA9PSBNVUxUX0VYUFIKCSAgICAgIC8qIElmIG5vdCBtdWx0aXBsaWNhdGlvbiwgd2UgY2FuIG9ubHkgZG8gdGhpcyBpZiBib3RoIG9wZXJhbmRzCgkJIGFyZSBkaXZpc2libGUgYnkgYy4gICovCgkgICAgICB8fCAobXVsdGlwbGVfb2ZfcCAoY3R5cGUsIG9wMCwgYykKCSAgICAgICAgICAmJiBtdWx0aXBsZV9vZl9wIChjdHlwZSwgb3AxLCBjKSkpKQoJcmV0dXJuIGZvbGQgKGJ1aWxkICh0Y29kZSwgY3R5cGUsIGZvbGRfY29udmVydCAoY3R5cGUsIHQxKSwKCQkJICAgIGZvbGRfY29udmVydCAoY3R5cGUsIHQyKSkpOwoKICAgICAgLyogSWYgdGhpcyB3YXMgYSBzdWJ0cmFjdGlvbiwgbmVnYXRlIE9QMSBhbmQgc2V0IGl0IHRvIGJlIGFuIGFkZGl0aW9uLgoJIFRoaXMgc2ltcGxpZmllcyB0aGUgbG9naWMgYmVsb3cuICAqLwogICAgICBpZiAodGNvZGUgPT0gTUlOVVNfRVhQUikKCXRjb2RlID0gUExVU19FWFBSLCBvcDEgPSBuZWdhdGVfZXhwciAob3AxKTsKCiAgICAgIGlmIChUUkVFX0NPREUgKG9wMSkgIT0gSU5URUdFUl9DU1QpCglicmVhazsKCiAgICAgIC8qIElmIGVpdGhlciBPUDEgb3IgQyBhcmUgbmVnYXRpdmUsIHRoaXMgb3B0aW1pemF0aW9uIGlzIG5vdCBzYWZlIGZvcgoJIHNvbWUgb2YgdGhlIGRpdmlzaW9uIGFuZCByZW1haW5kZXIgdHlwZXMgd2hpbGUgZm9yIG90aGVycyB3ZSBuZWVkCgkgdG8gY2hhbmdlIHRoZSBjb2RlLiAgKi8KICAgICAgaWYgKHRyZWVfaW50X2NzdF9zZ24gKG9wMSkgPCAwIHx8IHRyZWVfaW50X2NzdF9zZ24gKGMpIDwgMCkKCXsKCSAgaWYgKGNvZGUgPT0gQ0VJTF9ESVZfRVhQUikKCSAgICBjb2RlID0gRkxPT1JfRElWX0VYUFI7CgkgIGVsc2UgaWYgKGNvZGUgPT0gRkxPT1JfRElWX0VYUFIpCgkgICAgY29kZSA9IENFSUxfRElWX0VYUFI7CgkgIGVsc2UgaWYgKGNvZGUgIT0gTVVMVF9FWFBSCgkJICAgJiYgY29kZSAhPSBDRUlMX01PRF9FWFBSICYmIGNvZGUgIT0gRkxPT1JfTU9EX0VYUFIpCgkgICAgYnJlYWs7Cgl9CgogICAgICAvKiBJZiBpdCdzIGEgbXVsdGlwbHkgb3IgYSBkaXZpc2lvbi9tb2R1bHVzIG9wZXJhdGlvbiBvZiBhIG11bHRpcGxlCiAgICAgICAgIG9mIG91ciBjb25zdGFudCwgZG8gdGhlIG9wZXJhdGlvbiBhbmQgdmVyaWZ5IGl0IGRvZXNuJ3Qgb3ZlcmZsb3cuICAqLwogICAgICBpZiAoY29kZSA9PSBNVUxUX0VYUFIKCSAgfHwgaW50ZWdlcl96ZXJvcCAoY29uc3RfYmlub3AgKFRSVU5DX01PRF9FWFBSLCBvcDEsIGMsIDApKSkKCXsKCSAgb3AxID0gY29uc3RfYmlub3AgKGNvZGUsIGZvbGRfY29udmVydCAoY3R5cGUsIG9wMSksCgkJCSAgICAgZm9sZF9jb252ZXJ0IChjdHlwZSwgYyksIDApOwoJICAvKiBXZSBhbGxvdyB0aGUgY29uc3RhbnQgdG8gb3ZlcmZsb3cgd2l0aCB3cmFwcGluZyBzZW1hbnRpY3MuICAqLwoJICBpZiAob3AxID09IDAKCSAgICAgIHx8IChUUkVFX09WRVJGTE9XIChvcDEpICYmICEgZmxhZ193cmFwdikpCgkgICAgYnJlYWs7Cgl9CiAgICAgIGVsc2UKCWJyZWFrOwoKICAgICAgLyogSWYgd2UgaGF2ZSBhbiB1bnNpZ25lZCB0eXBlIGlzIG5vdCBhIHNpemV0eXBlLCB3ZSBjYW5ub3Qgd2lkZW4KCSB0aGUgb3BlcmF0aW9uIHNpbmNlIGl0IHdpbGwgY2hhbmdlIHRoZSByZXN1bHQgaWYgdGhlIG9yaWdpbmFsCgkgY29tcHV0YXRpb24gb3ZlcmZsb3dlZC4gICovCiAgICAgIGlmIChUUkVFX1VOU0lHTkVEIChjdHlwZSkKCSAgJiYgISAoVFJFRV9DT0RFIChjdHlwZSkgPT0gSU5URUdFUl9UWVBFICYmIFRZUEVfSVNfU0laRVRZUEUgKGN0eXBlKSkKCSAgJiYgY3R5cGUgIT0gdHlwZSkKCWJyZWFrOwoKICAgICAgLyogSWYgd2Ugd2VyZSBhYmxlIHRvIGVsaW1pbmF0ZSBvdXIgb3BlcmF0aW9uIGZyb20gdGhlIGZpcnN0IHNpZGUsCgkgYXBwbHkgb3VyIG9wZXJhdGlvbiB0byB0aGUgc2Vjb25kIHNpZGUgYW5kIHJlZm9ybSB0aGUgUExVUy4gICovCiAgICAgIGlmICh0MSAhPSAwICYmIChUUkVFX0NPREUgKHQxKSAhPSBjb2RlIHx8IGNvZGUgPT0gTVVMVF9FWFBSKSkKCXJldHVybiBmb2xkIChidWlsZCAodGNvZGUsIGN0eXBlLCBmb2xkX2NvbnZlcnQgKGN0eXBlLCB0MSksIG9wMSkpOwoKICAgICAgLyogVGhlIGxhc3QgY2FzZSBpcyBpZiB3ZSBhcmUgYSBtdWx0aXBseS4gIEluIHRoYXQgY2FzZSwgd2UgY2FuCgkgYXBwbHkgdGhlIGRpc3RyaWJ1dGl2ZSBsYXcgdG8gY29tbXV0ZSB0aGUgbXVsdGlwbHkgYW5kIGFkZGl0aW9uCgkgaWYgdGhlIG11bHRpcGxpY2F0aW9uIG9mIHRoZSBjb25zdGFudHMgZG9lc24ndCBvdmVyZmxvdy4gICovCiAgICAgIGlmIChjb2RlID09IE1VTFRfRVhQUikKCXJldHVybiBmb2xkIChidWlsZCAodGNvZGUsIGN0eXBlLAoJCQkgICAgZm9sZCAoYnVpbGQgKGNvZGUsIGN0eXBlLAoJCQkJCSBmb2xkX2NvbnZlcnQgKGN0eXBlLCBvcDApLAoJCQkJCSBmb2xkX2NvbnZlcnQgKGN0eXBlLCBjKSkpLAoJCQkgICAgb3AxKSk7CgogICAgICBicmVhazsKCiAgICBjYXNlIE1VTFRfRVhQUjoKICAgICAgLyogV2UgaGF2ZSBhIHNwZWNpYWwgY2FzZSBoZXJlIGlmIHdlIGFyZSBkb2luZyBzb21ldGhpbmcgbGlrZQoJIChDICogOCkgJSA0IHNpbmNlIHdlIGtub3cgdGhhdCdzIHplcm8uICAqLwogICAgICBpZiAoKGNvZGUgPT0gVFJVTkNfTU9EX0VYUFIgfHwgY29kZSA9PSBDRUlMX01PRF9FWFBSCgkgICB8fCBjb2RlID09IEZMT09SX01PRF9FWFBSIHx8IGNvZGUgPT0gUk9VTkRfTU9EX0VYUFIpCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EICh0LCAxKSkgPT0gSU5URUdFUl9DU1QKCSAgJiYgaW50ZWdlcl96ZXJvcCAoY29uc3RfYmlub3AgKFRSVU5DX01PRF9FWFBSLCBvcDEsIGMsIDApKSkKCXJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSwgb3AwKTsKCiAgICAgIC8qIC4uLiBmYWxsIHRocm91Z2ggLi4uICAqLwoKICAgIGNhc2UgVFJVTkNfRElWX0VYUFI6ICBjYXNlIENFSUxfRElWX0VYUFI6ICBjYXNlIEZMT09SX0RJVl9FWFBSOgogICAgY2FzZSBST1VORF9ESVZfRVhQUjogIGNhc2UgRVhBQ1RfRElWX0VYUFI6CiAgICAgIC8qIElmIHdlIGNhbiBleHRyYWN0IG91ciBvcGVyYXRpb24gZnJvbSB0aGUgTEhTLCBkbyBzbyBhbmQgcmV0dXJuIGEKCSBuZXcgb3BlcmF0aW9uLiAgTGlrZXdpc2UgZm9yIHRoZSBSSFMgZnJvbSBhIE1VTFRfRVhQUi4gIE90aGVyd2lzZSwKCSBkbyBzb21ldGhpbmcgb25seSBpZiB0aGUgc2Vjb25kIG9wZXJhbmQgaXMgYSBjb25zdGFudC4gICovCiAgICAgIGlmIChzYW1lX3AKCSAgJiYgKHQxID0gZXh0cmFjdF9tdWxkaXYgKG9wMCwgYywgY29kZSwgd2lkZV90eXBlKSkgIT0gMCkKCXJldHVybiBmb2xkIChidWlsZCAodGNvZGUsIGN0eXBlLCBmb2xkX2NvbnZlcnQgKGN0eXBlLCB0MSksCgkJCSAgICBmb2xkX2NvbnZlcnQgKGN0eXBlLCBvcDEpKSk7CiAgICAgIGVsc2UgaWYgKHRjb2RlID09IE1VTFRfRVhQUiAmJiBjb2RlID09IE1VTFRfRVhQUgoJICAgICAgICYmICh0MSA9IGV4dHJhY3RfbXVsZGl2IChvcDEsIGMsIGNvZGUsIHdpZGVfdHlwZSkpICE9IDApCglyZXR1cm4gZm9sZCAoYnVpbGQgKHRjb2RlLCBjdHlwZSwgZm9sZF9jb252ZXJ0IChjdHlwZSwgb3AwKSwKCQkJICAgIGZvbGRfY29udmVydCAoY3R5cGUsIHQxKSkpOwogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKG9wMSkgIT0gSU5URUdFUl9DU1QpCglyZXR1cm4gMDsKCiAgICAgIC8qIElmIHRoZXNlIGFyZSB0aGUgc2FtZSBvcGVyYXRpb24gdHlwZXMsIHdlIGNhbiBhc3NvY2lhdGUgdGhlbQoJIGFzc3VtaW5nIG5vIG92ZXJmbG93LiAgKi8KICAgICAgaWYgKHRjb2RlID09IGNvZGUKCSAgJiYgMCAhPSAodDEgPSBjb25zdF9iaW5vcCAoTVVMVF9FWFBSLCBmb2xkX2NvbnZlcnQgKGN0eXBlLCBvcDEpLAoJCQkJICAgICBmb2xkX2NvbnZlcnQgKGN0eXBlLCBjKSwgMCkpCgkgICYmICEgVFJFRV9PVkVSRkxPVyAodDEpKQoJcmV0dXJuIGZvbGQgKGJ1aWxkICh0Y29kZSwgY3R5cGUsIGZvbGRfY29udmVydCAoY3R5cGUsIG9wMCksIHQxKSk7CgogICAgICAvKiBJZiB0aGVzZSBvcGVyYXRpb25zICJjYW5jZWwiIGVhY2ggb3RoZXIsIHdlIGhhdmUgdGhlIG1haW4KCSBvcHRpbWl6YXRpb25zIG9mIHRoaXMgcGFzcywgd2hpY2ggb2NjdXIgd2hlbiBlaXRoZXIgY29uc3RhbnQgaXMgYQoJIG11bHRpcGxlIG9mIHRoZSBvdGhlciwgaW4gd2hpY2ggY2FzZSB3ZSByZXBsYWNlIHRoaXMgd2l0aCBlaXRoZXIgYW4KCSBvcGVyYXRpb24gb3IgQ09ERSBvciBUQ09ERS4KCgkgSWYgd2UgaGF2ZSBhbiB1bnNpZ25lZCB0eXBlIHRoYXQgaXMgbm90IGEgc2l6ZXR5cGUsIHdlIGNhbm5vdCBkbwoJIHRoaXMgc2luY2UgaXQgd2lsbCBjaGFuZ2UgdGhlIHJlc3VsdCBpZiB0aGUgb3JpZ2luYWwgY29tcHV0YXRpb24KCSBvdmVyZmxvd2VkLiAgKi8KICAgICAgaWYgKCghIFRSRUVfVU5TSUdORUQgKGN0eXBlKQoJICAgfHwgKFRSRUVfQ09ERSAoY3R5cGUpID09IElOVEVHRVJfVFlQRSAmJiBUWVBFX0lTX1NJWkVUWVBFIChjdHlwZSkpKQoJICAmJiAhIGZsYWdfd3JhcHYKCSAgJiYgKChjb2RlID09IE1VTFRfRVhQUiAmJiB0Y29kZSA9PSBFWEFDVF9ESVZfRVhQUikKCSAgICAgIHx8ICh0Y29kZSA9PSBNVUxUX0VYUFIKCQkgICYmIGNvZGUgIT0gVFJVTkNfTU9EX0VYUFIgJiYgY29kZSAhPSBDRUlMX01PRF9FWFBSCgkJICAmJiBjb2RlICE9IEZMT09SX01PRF9FWFBSICYmIGNvZGUgIT0gUk9VTkRfTU9EX0VYUFIpKSkKCXsKCSAgaWYgKGludGVnZXJfemVyb3AgKGNvbnN0X2Jpbm9wIChUUlVOQ19NT0RfRVhQUiwgb3AxLCBjLCAwKSkpCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkICh0Y29kZSwgY3R5cGUsIGZvbGRfY29udmVydCAoY3R5cGUsIG9wMCksCgkJCQlmb2xkX2NvbnZlcnQgKGN0eXBlLAoJCQkJCSAgICAgIGNvbnN0X2Jpbm9wIChUUlVOQ19ESVZfRVhQUiwKCQkJCQkJCSAgIG9wMSwgYywgMCkpKSk7CgkgIGVsc2UgaWYgKGludGVnZXJfemVyb3AgKGNvbnN0X2Jpbm9wIChUUlVOQ19NT0RfRVhQUiwgYywgb3AxLCAwKSkpCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChjb2RlLCBjdHlwZSwgZm9sZF9jb252ZXJ0IChjdHlwZSwgb3AwKSwKCQkJCWZvbGRfY29udmVydCAoY3R5cGUsCgkJCQkJICAgICAgY29uc3RfYmlub3AgKFRSVU5DX0RJVl9FWFBSLAoJCQkJCQkJICAgYywgb3AxLCAwKSkpKTsKCX0KICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgICB9CgogIHJldHVybiAwOwp9CgwKLyogSWYgVCBjb250YWlucyBhIENPTVBPVU5EX0VYUFIgd2hpY2ggd2FzIGluc2VydGVkIG1lcmVseSB0byBldmFsdWF0ZQogICBTLCBhIFNBVkVfRVhQUiwgcmV0dXJuIHRoZSBleHByZXNzaW9uIGFjdHVhbGx5IGJlaW5nIGV2YWx1YXRlZC4gICBOb3RlCiAgIHRoYXQgd2UgbWF5IHNvbWV0aW1lcyBtb2RpZnkgdGhlIHRyZWUuICAqLwoKc3RhdGljIHRyZWUKc3RyaXBfY29tcG91bmRfZXhwciAodHJlZSB0LCB0cmVlIHMpCnsKICBlbnVtIHRyZWVfY29kZSBjb2RlID0gVFJFRV9DT0RFICh0KTsKCiAgLyogU2VlIGlmIHRoaXMgaXMgdGhlIENPTVBPVU5EX0VYUFIgd2Ugd2FudCB0byBlbGltaW5hdGUuICAqLwogIGlmIChjb2RlID09IENPTVBPVU5EX0VYUFIgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHQsIDApKSA9PSBDT05WRVJUX0VYUFIKICAgICAgJiYgVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDApLCAwKSA9PSBzKQogICAgcmV0dXJuIFRSRUVfT1BFUkFORCAodCwgMSk7CgogIC8qIFNlZSBpZiB0aGlzIGlzIGEgQ09ORF9FWFBSIG9yIGEgc2ltcGxlIGFyaXRobWV0aWMgb3BlcmF0b3IuICAgV2UKICAgICBkb24ndCBib3RoZXIgaGFuZGxpbmcgYW55IG90aGVyIHR5cGVzLiAgKi8KICBlbHNlIGlmIChjb2RlID09IENPTkRfRVhQUikKICAgIHsKICAgICAgVFJFRV9PUEVSQU5EICh0LCAwKSA9IHN0cmlwX2NvbXBvdW5kX2V4cHIgKFRSRUVfT1BFUkFORCAodCwgMCksIHMpOwogICAgICBUUkVFX09QRVJBTkQgKHQsIDEpID0gc3RyaXBfY29tcG91bmRfZXhwciAoVFJFRV9PUEVSQU5EICh0LCAxKSwgcyk7CiAgICAgIFRSRUVfT1BFUkFORCAodCwgMikgPSBzdHJpcF9jb21wb3VuZF9leHByIChUUkVFX09QRVJBTkQgKHQsIDIpLCBzKTsKICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREVfQ0xBU1MgKGNvZGUpID09ICcxJykKICAgIFRSRUVfT1BFUkFORCAodCwgMCkgPSBzdHJpcF9jb21wb3VuZF9leHByIChUUkVFX09QRVJBTkQgKHQsIDApLCBzKTsKICBlbHNlIGlmIChUUkVFX0NPREVfQ0xBU1MgKGNvZGUpID09ICc8JwoJICAgfHwgVFJFRV9DT0RFX0NMQVNTIChjb2RlKSA9PSAnMicpCiAgICB7CiAgICAgIFRSRUVfT1BFUkFORCAodCwgMCkgPSBzdHJpcF9jb21wb3VuZF9leHByIChUUkVFX09QRVJBTkQgKHQsIDApLCBzKTsKICAgICAgVFJFRV9PUEVSQU5EICh0LCAxKSA9IHN0cmlwX2NvbXBvdW5kX2V4cHIgKFRSRUVfT1BFUkFORCAodCwgMSksIHMpOwogICAgfQoKICByZXR1cm4gdDsKfQoMCi8qIFJldHVybiBhIG5vZGUgd2hpY2ggaGFzIHRoZSBpbmRpY2F0ZWQgY29uc3RhbnQgVkFMVUUgKGVpdGhlciAwIG9yCiAgIDEpLCBhbmQgaXMgb2YgdGhlIGluZGljYXRlZCBUWVBFLiAgKi8KCnN0YXRpYyB0cmVlCmNvbnN0YW50X2Jvb2xlYW5fbm9kZSAoaW50IHZhbHVlLCB0cmVlIHR5cGUpCnsKICBpZiAodHlwZSA9PSBpbnRlZ2VyX3R5cGVfbm9kZSkKICAgIHJldHVybiB2YWx1ZSA/IGludGVnZXJfb25lX25vZGUgOiBpbnRlZ2VyX3plcm9fbm9kZTsKICBlbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEJPT0xFQU5fVFlQRSkKICAgIHJldHVybiAoKmxhbmdfaG9va3MudHJ1dGh2YWx1ZV9jb252ZXJzaW9uKSAodmFsdWUgPyBpbnRlZ2VyX29uZV9ub2RlIDoKCQkJCQkJaW50ZWdlcl96ZXJvX25vZGUpOwogIGVsc2UKICAgIHsKICAgICAgdHJlZSB0ID0gYnVpbGRfaW50XzIgKHZhbHVlLCAwKTsKCiAgICAgIFRSRUVfVFlQRSAodCkgPSB0eXBlOwogICAgICByZXR1cm4gdDsKICAgIH0KfQoKLyogVXRpbGl0eSBmdW5jdGlvbiBmb3IgdGhlIGZvbGxvd2luZyByb3V0aW5lLCB0byBzZWUgaG93IGNvbXBsZXggYSBuZXN0aW5nIG9mCiAgIENPTkRfRVhQUnMgY2FuIGJlLiAgRVhQUiBpcyB0aGUgZXhwcmVzc2lvbiBhbmQgTElNSVQgaXMgYSBjb3VudCBiZXlvbmQgd2hpY2gKICAgd2UgZG9uJ3QgY2FyZSAodG8gYXZvaWQgc3BlbmRpbmcgdG9vIG11Y2ggdGltZSBvbiBjb21wbGV4IGV4cHJlc3Npb25zLikuICAqLwoKc3RhdGljIGludApjb3VudF9jb25kICh0cmVlIGV4cHIsIGludCBsaW0pCnsKICBpbnQgY3RydWUsIGNmYWxzZTsKCiAgaWYgKFRSRUVfQ09ERSAoZXhwcikgIT0gQ09ORF9FWFBSKQogICAgcmV0dXJuIDA7CiAgZWxzZSBpZiAobGltIDw9IDApCiAgICByZXR1cm4gMDsKCiAgY3RydWUgPSBjb3VudF9jb25kIChUUkVFX09QRVJBTkQgKGV4cHIsIDEpLCBsaW0gLSAxKTsKICBjZmFsc2UgPSBjb3VudF9jb25kIChUUkVFX09QRVJBTkQgKGV4cHIsIDIpLCBsaW0gLSAxIC0gY3RydWUpOwogIHJldHVybiBNSU4gKGxpbSwgMSArIGN0cnVlICsgY2ZhbHNlKTsKfQoKLyogVHJhbnNmb3JtIGBhICsgKGIgPyB4IDogeSknIGludG8gYGIgPyAoYSArIHgpIDogKGEgKyB5KScuCiAgIFRyYW5zZm9ybSwgYGEgKyAoeCA8IHkpJyBpbnRvIGAoeCA8IHkpID8gKGEgKyAxKSA6IChhICsgMCknLiAgSGVyZQogICBDT0RFIGNvcnJlc3BvbmRzIHRvIHRoZSBgKycsIENPTkQgdG8gdGhlIGAoYiA/IHggOiB5KScgb3IgYCh4IDwgeSknCiAgIGV4cHJlc3Npb24sIGFuZCBBUkcgdG8gYGEnLiAgSWYgQ09ORF9GSVJTVF9QIGlzIG5vbnplcm8sIHRoZW4gdGhlCiAgIENPTkQgaXMgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIENPREU7IG90aGVyd2lzZSAoYXMgaW4gdGhlIGV4YW1wbGUKICAgZ2l2ZW4gaGVyZSksIGl0IGlzIHRoZSBzZWNvbmQgYXJndW1lbnQuICBUWVBFIGlzIHRoZSB0eXBlIG9mIHRoZQogICBvcmlnaW5hbCBleHByZXNzaW9uLiAgKi8KCnN0YXRpYyB0cmVlCmZvbGRfYmluYXJ5X29wX3dpdGhfY29uZGl0aW9uYWxfYXJnIChlbnVtIHRyZWVfY29kZSBjb2RlLCB0cmVlIHR5cGUsCgkJCQkgICAgIHRyZWUgY29uZCwgdHJlZSBhcmcsIGludCBjb25kX2ZpcnN0X3ApCnsKICB0cmVlIHRlc3QsIHRydWVfdmFsdWUsIGZhbHNlX3ZhbHVlOwogIHRyZWUgbGhzID0gTlVMTF9UUkVFOwogIHRyZWUgcmhzID0gTlVMTF9UUkVFOwogIC8qIEluIHRoZSBlbmQsIHdlJ2xsIHByb2R1Y2UgYSBDT05EX0VYUFIuICBCb3RoIGFybXMgb2YgdGhlCiAgICAgY29uZGl0aW9uYWwgZXhwcmVzc2lvbiB3aWxsIGJlIGJpbmFyeSBvcGVyYXRpb25zLiAgVGhlIGxlZnQtaGFuZAogICAgIHNpZGUgb2YgdGhlIGV4cHJlc3Npb24gdG8gYmUgZXhlY3V0ZWQgaWYgdGhlIGNvbmRpdGlvbiBpcyB0cnVlCiAgICAgd2lsbCBiZSBwb2ludGVkIHRvIGJ5IFRSVUVfTEhTLiAgU2ltaWxhcmx5LCB0aGUgcmlnaHQtaGFuZCBzaWRlCiAgICAgb2YgdGhlIGV4cHJlc3Npb24gdG8gYmUgZXhlY3V0ZWQgaWYgdGhlIGNvbmRpdGlvbiBpcyB0cnVlIHdpbGwgYmUKICAgICBwb2ludGVkIHRvIGJ5IFRSVUVfUkhTLiAgRkFMU0VfTEhTIGFuZCBGQUxTRV9SSFMgYXJlIGFuYWxvZ291cyAtLQogICAgIGJ1dCBhcHBseSB0byB0aGUgZXhwcmVzc2lvbiB0byBiZSBleGVjdXRlZCBpZiB0aGUgY29uZGl0aW9uYWwgaXMKICAgICBmYWxzZS4gICovCiAgdHJlZSAqdHJ1ZV9saHM7CiAgdHJlZSAqdHJ1ZV9yaHM7CiAgdHJlZSAqZmFsc2VfbGhzOwogIHRyZWUgKmZhbHNlX3JoczsKICAvKiBUaGVzZSBhcmUgdGhlIGNvZGVzIHRvIHVzZSBmb3IgdGhlIGxlZnQtaGFuZCBzaWRlIGFuZCByaWdodC1oYW5kCiAgICAgc2lkZSBvZiB0aGUgQ09ORF9FWFBSLiAgTm9ybWFsbHksIHRoZXkgYXJlIHRoZSBzYW1lIGFzIENPREUuICAqLwogIGVudW0gdHJlZV9jb2RlIGxoc19jb2RlID0gY29kZTsKICBlbnVtIHRyZWVfY29kZSByaHNfY29kZSA9IGNvZGU7CiAgLyogQW5kIHRoZXNlIGFyZSB0aGUgdHlwZXMgb2YgdGhlIGV4cHJlc3Npb25zLiAgKi8KICB0cmVlIGxoc190eXBlID0gdHlwZTsKICB0cmVlIHJoc190eXBlID0gdHlwZTsKICBpbnQgc2F2ZSA9IDA7CgogIGlmIChjb25kX2ZpcnN0X3ApCiAgICB7CiAgICAgIHRydWVfcmhzID0gZmFsc2VfcmhzID0gJmFyZzsKICAgICAgdHJ1ZV9saHMgPSAmdHJ1ZV92YWx1ZTsKICAgICAgZmFsc2VfbGhzID0gJmZhbHNlX3ZhbHVlOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgdHJ1ZV9saHMgPSBmYWxzZV9saHMgPSAmYXJnOwogICAgICB0cnVlX3JocyA9ICZ0cnVlX3ZhbHVlOwogICAgICBmYWxzZV9yaHMgPSAmZmFsc2VfdmFsdWU7CiAgICB9CgogIGlmIChUUkVFX0NPREUgKGNvbmQpID09IENPTkRfRVhQUikKICAgIHsKICAgICAgdGVzdCA9IFRSRUVfT1BFUkFORCAoY29uZCwgMCk7CiAgICAgIHRydWVfdmFsdWUgPSBUUkVFX09QRVJBTkQgKGNvbmQsIDEpOwogICAgICBmYWxzZV92YWx1ZSA9IFRSRUVfT1BFUkFORCAoY29uZCwgMik7CiAgICAgIC8qIElmIHRoaXMgb3BlcmFuZCB0aHJvd3MgYW4gZXhwcmVzc2lvbiwgdGhlbiBpdCBkb2VzIG5vdCBtYWtlCgkgc2Vuc2UgdG8gdHJ5IHRvIHBlcmZvcm0gYSBsb2dpY2FsIG9yIGFyaXRobWV0aWMgb3BlcmF0aW9uCgkgaW52b2x2aW5nIGl0LiAgSW5zdGVhZCBvZiBidWlsZGluZyBgYSArIHRocm93IDMnIGZvciBleGFtcGxlLAoJIHdlIHNpbXBseSBidWlsZCBgYSwgdGhyb3cgMycuICAqLwogICAgICBpZiAoVk9JRF9UWVBFX1AgKFRSRUVfVFlQRSAodHJ1ZV92YWx1ZSkpKQoJewoJICBpZiAoISBjb25kX2ZpcnN0X3ApCgkgICAgewoJICAgICAgbGhzX2NvZGUgPSBDT01QT1VORF9FWFBSOwoJICAgICAgbGhzX3R5cGUgPSB2b2lkX3R5cGVfbm9kZTsKCSAgICB9CgkgIGVsc2UKCSAgICBsaHMgPSB0cnVlX3ZhbHVlOwoJfQogICAgICBpZiAoVk9JRF9UWVBFX1AgKFRSRUVfVFlQRSAoZmFsc2VfdmFsdWUpKSkKCXsKCSAgaWYgKCEgY29uZF9maXJzdF9wKQoJICAgIHsKCSAgICAgIHJoc19jb2RlID0gQ09NUE9VTkRfRVhQUjsKCSAgICAgIHJoc190eXBlID0gdm9pZF90eXBlX25vZGU7CgkgICAgfQoJICBlbHNlCgkgICAgcmhzID0gZmFsc2VfdmFsdWU7Cgl9CiAgICB9CiAgZWxzZQogICAgewogICAgICB0cmVlIHRlc3R0eXBlID0gVFJFRV9UWVBFIChjb25kKTsKICAgICAgdGVzdCA9IGNvbmQ7CiAgICAgIHRydWVfdmFsdWUgPSBmb2xkX2NvbnZlcnQgKHRlc3R0eXBlLCBpbnRlZ2VyX29uZV9ub2RlKTsKICAgICAgZmFsc2VfdmFsdWUgPSBmb2xkX2NvbnZlcnQgKHRlc3R0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSk7CiAgICB9CgogIC8qIElmIEFSRyBpcyBjb21wbGV4IHdlIHdhbnQgdG8gbWFrZSBzdXJlIHdlIG9ubHkgZXZhbHVhdGUgaXQgb25jZS4gIFRob3VnaAogICAgIHRoaXMgaXMgb25seSByZXF1aXJlZCBpZiBpdCBpcyB2b2xhdGlsZSwgaXQgbWlnaHQgYmUgbW9yZSBlZmZpY2llbnQgZXZlbgogICAgIGlmIGl0IGlzIG5vdC4gIEhvd2V2ZXIsIGlmIHdlIHN1Y2NlZWQgaW4gZm9sZGluZyBvbmUgcGFydCB0byBhIGNvbnN0YW50LAogICAgIHdlIGRvIG5vdCBuZWVkIHRvIG1ha2UgdGhpcyBTQVZFX0VYUFIuICBTaW5jZSB3ZSBkbyB0aGlzIG9wdGltaXphdGlvbgogICAgIHByaW1hcmlseSB0byBzZWUgaWYgd2UgZG8gZW5kIHVwIHdpdGggY29uc3RhbnQgYW5kIHRoaXMgU0FWRV9FWFBSCiAgICAgaW50ZXJmZXJlcyB3aXRoIGxhdGVyIG9wdGltaXphdGlvbnMsIHN1cHByZXNzaW5nIGl0IHdoZW4gd2UgY2FuIGlzCiAgICAgaW1wb3J0YW50LgoKICAgICBJZiB3ZSBhcmUgbm90IGluIGEgZnVuY3Rpb24sIHdlIGNhbid0IG1ha2UgYSBTQVZFX0VYUFIsIHNvIGRvbid0IHRyeSB0bwogICAgIGRvIHNvLiAgRG9uJ3QgdHJ5IHRvIHNlZSBpZiB0aGUgcmVzdWx0IGlzIGEgY29uc3RhbnQgaWYgYW4gYXJtIGlzIGEKICAgICBDT05EX0VYUFIgc2luY2Ugd2UgZ2V0IGV4cG9uZW50aWFsIGJlaGF2aW9yIGluIHRoYXQgY2FzZS4gICovCgogIGlmIChzYXZlZF9leHByX3AgKGFyZykpCiAgICBzYXZlID0gMTsKICBlbHNlIGlmIChsaHMgPT0gMCAmJiByaHMgPT0gMAoJICAgJiYgIVRSRUVfQ09OU1RBTlQgKGFyZykKCSAgICYmICgqbGFuZ19ob29rcy5kZWNscy5nbG9iYWxfYmluZGluZ3NfcCkgKCkgPT0gMAoJICAgJiYgKChUUkVFX0NPREUgKGFyZykgIT0gVkFSX0RFQ0wgJiYgVFJFRV9DT0RFIChhcmcpICE9IFBBUk1fREVDTCkKCSAgICAgICB8fCBUUkVFX1NJREVfRUZGRUNUUyAoYXJnKSkpCiAgICB7CiAgICAgIGlmIChUUkVFX0NPREUgKHRydWVfdmFsdWUpICE9IENPTkRfRVhQUikKCWxocyA9IGZvbGQgKGJ1aWxkIChsaHNfY29kZSwgbGhzX3R5cGUsICp0cnVlX2xocywgKnRydWVfcmhzKSk7CgogICAgICBpZiAoVFJFRV9DT0RFIChmYWxzZV92YWx1ZSkgIT0gQ09ORF9FWFBSKQoJcmhzID0gZm9sZCAoYnVpbGQgKHJoc19jb2RlLCByaHNfdHlwZSwgKmZhbHNlX2xocywgKmZhbHNlX3JocykpOwoKICAgICAgaWYgKChsaHMgPT0gMCB8fCAhIFRSRUVfQ09OU1RBTlQgKGxocykpCgkgICYmIChyaHMgPT0gMCB8fCAhVFJFRV9DT05TVEFOVCAocmhzKSkpCgl7CgkgIGFyZyA9IHNhdmVfZXhwciAoYXJnKTsKCSAgbGhzID0gcmhzID0gMDsKCSAgc2F2ZSA9IHNhdmVkX2V4cHJfcCAoYXJnKTsKCX0KICAgIH0KCiAgaWYgKGxocyA9PSAwKQogICAgbGhzID0gZm9sZCAoYnVpbGQgKGxoc19jb2RlLCBsaHNfdHlwZSwgKnRydWVfbGhzLCAqdHJ1ZV9yaHMpKTsKICBpZiAocmhzID09IDApCiAgICByaHMgPSBmb2xkIChidWlsZCAocmhzX2NvZGUsIHJoc190eXBlLCAqZmFsc2VfbGhzLCAqZmFsc2VfcmhzKSk7CgogIHRlc3QgPSBmb2xkIChidWlsZCAoQ09ORF9FWFBSLCB0eXBlLCB0ZXN0LCBsaHMsIHJocykpOwoKICAvKiBJZiBBUkcgaW52b2x2ZXMgYSBTQVZFX0VYUFIsIHdlIG5lZWQgdG8gZW5zdXJlIGl0IGlzIGV2YWx1YXRlZAogICAgIGFoZWFkIG9mIHRoZSBDT05EX0VYUFIgd2UgbWFkZS4gIE90aGVyd2lzZSB3ZSB3b3VsZCBoYXZlIGl0IG9ubHkKICAgICBldmFsdWF0ZWQgaW4gb25lIGJyYW5jaCwgd2l0aCB0aGUgb3RoZXIgYnJhbmNoIHVzaW5nIHRoZSByZXN1bHQKICAgICBidXQgbWlzc2luZyB0aGUgZXZhbHVhdGlvbiBjb2RlLiAgQmV3YXJlIHRoYXQgdGhlIHNhdmVfZXhwciBjYWxsCiAgICAgYWJvdmUgbWlnaHQgbm90IHJldHVybiBhIFNBVkVfRVhQUiwgc28gdGVzdGluZyB0aGUgVFJFRV9DT0RFCiAgICAgb2YgQVJHIGlzIG5vdCBlbm91Z2ggdG8gZGVjaWRlIGhlcmUuIKAqLwogIGlmIChzYXZlKQogICAgcmV0dXJuIGJ1aWxkIChDT01QT1VORF9FWFBSLCB0eXBlLAoJCSAgZm9sZF9jb252ZXJ0ICh2b2lkX3R5cGVfbm9kZSwgYXJnKSwKCQkgIHN0cmlwX2NvbXBvdW5kX2V4cHIgKHRlc3QsIGFyZykpOwogIGVsc2UKICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIHRlc3QpOwp9CgoMCi8qIFN1YnJvdXRpbmUgb2YgZm9sZCgpIHRoYXQgY2hlY2tzIGZvciB0aGUgYWRkaXRpb24gb2YgKy8tIDAuMC4KCiAgIElmICFORUdBVEUsIHJldHVybiB0cnVlIGlmIEFEREVORCBpcyArLy0wLjAgYW5kLCBmb3IgYWxsIFggb2YgdHlwZQogICBUWVBFLCBYICsgQURERU5EIGlzIHRoZSBzYW1lIGFzIFguICBJZiBORUdBVEUsIHJldHVybiB0cnVlIGlmIFggLQogICBBRERFTkQgaXMgdGhlIHNhbWUgYXMgWC4KCiAgIFggKyAwIGFuZCBYIC0gMCBib3RoIGdpdmUgWCB3aGVuIFggaXMgTmFOLCBpbmZpbml0ZSwgb3Igbm9uemVybwogICBhbmQgZmluaXRlLiAgVGhlIHByb2JsZW1hdGljIGNhc2VzIGFyZSB3aGVuIFggaXMgemVybywgYW5kIGl0cyBtb2RlCiAgIGhhcyBzaWduZWQgemVyb3MuICBJbiB0aGUgY2FzZSBvZiByb3VuZGluZyB0b3dhcmRzIC1pbmZpbml0eSwKICAgWCAtIDAgaXMgbm90IHRoZSBzYW1lIGFzIFggYmVjYXVzZSAwIC0gMCBpcyAtMC4gIEluIG90aGVyIHJvdW5kaW5nCiAgIG1vZGVzLCBYICsgMCBpcyBub3QgdGhlIHNhbWUgYXMgWCBiZWNhdXNlIC0wICsgMCBpcyAwLiAgKi8KCnN0YXRpYyBib29sCmZvbGRfcmVhbF96ZXJvX2FkZGl0aW9uX3AgKHRyZWUgdHlwZSwgdHJlZSBhZGRlbmQsIGludCBuZWdhdGUpCnsKICBpZiAoIXJlYWxfemVyb3AgKGFkZGVuZCkpCiAgICByZXR1cm4gZmFsc2U7CgogIC8qIERvbid0IGFsbG93IHRoZSBmb2xkIHdpdGggLWZzaWduYWxpbmctbmFucy4gICovCiAgaWYgKEhPTk9SX1NOQU5TIChUWVBFX01PREUgKHR5cGUpKSkKICAgIHJldHVybiBmYWxzZTsKCiAgLyogQWxsb3cgdGhlIGZvbGQgaWYgemVyb3MgYXJlbid0IHNpZ25lZCwgb3IgdGhlaXIgc2lnbiBpc24ndCBpbXBvcnRhbnQuICAqLwogIGlmICghSE9OT1JfU0lHTkVEX1pFUk9TIChUWVBFX01PREUgKHR5cGUpKSkKICAgIHJldHVybiB0cnVlOwoKICAvKiBUcmVhdCB4ICsgLTAgYXMgeCAtIDAgYW5kIHggLSAtMCBhcyB4ICsgMC4gICovCiAgaWYgKFRSRUVfQ09ERSAoYWRkZW5kKSA9PSBSRUFMX0NTVAogICAgICAmJiBSRUFMX1ZBTFVFX01JTlVTX1pFUk8gKFRSRUVfUkVBTF9DU1QgKGFkZGVuZCkpKQogICAgbmVnYXRlID0gIW5lZ2F0ZTsKCiAgLyogVGhlIG1vZGUgaGFzIHNpZ25lZCB6ZXJvcywgYW5kIHdlIGhhdmUgdG8gaG9ub3IgdGhlaXIgc2lnbi4KICAgICBJbiB0aGlzIHNpdHVhdGlvbiwgdGhlcmUgaXMgb25seSBvbmUgY2FzZSB3ZSBjYW4gcmV0dXJuIHRydWUgZm9yLgogICAgIFggLSAwIGlzIHRoZSBzYW1lIGFzIFggdW5sZXNzIHJvdW5kaW5nIHRvd2FyZHMgLWluZmluaXR5IGlzCiAgICAgc3VwcG9ydGVkLiAgKi8KICByZXR1cm4gbmVnYXRlICYmICFIT05PUl9TSUdOX0RFUEVOREVOVF9ST1VORElORyAoVFlQRV9NT0RFICh0eXBlKSk7Cn0KCi8qIFN1YnJvdXRpbmUgb2YgZm9sZCgpIHRoYXQgY2hlY2tzIGNvbXBhcmlzb25zIG9mIGJ1aWx0LWluIG1hdGgKICAgZnVuY3Rpb25zIGFnYWluc3QgcmVhbCBjb25zdGFudHMuCgogICBGQ09ERSBpcyB0aGUgREVDTF9GVU5DVElPTl9DT0RFIG9mIHRoZSBidWlsdC1pbiwgQ09ERSBpcyB0aGUgY29tcGFyaXNvbgogICBvcGVyYXRvcjogRVFfRVhQUiwgTkVfRVhQUiwgR1RfRVhQUiwgTFRfRVhQUiwgR0VfRVhQUiBvciBMRV9FWFBSLiAgVFlQRQogICBpcyB0aGUgdHlwZSBvZiB0aGUgcmVzdWx0IGFuZCBBUkcwIGFuZCBBUkcxIGFyZSB0aGUgb3BlcmFuZHMgb2YgdGhlCiAgIGNvbXBhcmlzb24uICBBUkcxIG11c3QgYmUgYSBUUkVFX1JFQUxfQ1NULgoKICAgVGhlIGZ1bmN0aW9uIHJldHVybnMgdGhlIGNvbnN0YW50IGZvbGRlZCB0cmVlIGlmIGEgc2ltcGxpZmljYXRpb24KICAgY2FuIGJlIG1hZGUsIGFuZCBOVUxMX1RSRUUgb3RoZXJ3aXNlLiAgKi8KCnN0YXRpYyB0cmVlCmZvbGRfbWF0aGZuX2NvbXBhcmUgKGVudW0gYnVpbHRfaW5fZnVuY3Rpb24gZmNvZGUsIGVudW0gdHJlZV9jb2RlIGNvZGUsCgkJICAgICB0cmVlIHR5cGUsIHRyZWUgYXJnMCwgdHJlZSBhcmcxKQp7CiAgUkVBTF9WQUxVRV9UWVBFIGM7CgogIGlmIChmY29kZSA9PSBCVUlMVF9JTl9TUVJUCiAgICAgIHx8IGZjb2RlID09IEJVSUxUX0lOX1NRUlRGCiAgICAgIHx8IGZjb2RlID09IEJVSUxUX0lOX1NRUlRMKQogICAgewogICAgICB0cmVlIGFyZyA9IFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpOwogICAgICBlbnVtIG1hY2hpbmVfbW9kZSBtb2RlID0gVFlQRV9NT0RFIChUUkVFX1RZUEUgKGFyZzApKTsKCiAgICAgIGMgPSBUUkVFX1JFQUxfQ1NUIChhcmcxKTsKICAgICAgaWYgKFJFQUxfVkFMVUVfTkVHQVRJVkUgKGMpKQoJewoJICAvKiBzcXJ0KHgpIDwgeSBpcyBhbHdheXMgZmFsc2UsIGlmIHkgaXMgbmVnYXRpdmUuICAqLwoJICBpZiAoY29kZSA9PSBFUV9FWFBSIHx8IGNvZGUgPT0gTFRfRVhQUiB8fCBjb2RlID09IExFX0VYUFIpCgkgICAgcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsCgkJCQkgICAgIGZvbGRfY29udmVydCAodHlwZSwgaW50ZWdlcl96ZXJvX25vZGUpLAoJCQkJICAgICBhcmcpOwoKCSAgLyogc3FydCh4KSA+IHkgaXMgYWx3YXlzIHRydWUsIGlmIHkgaXMgbmVnYXRpdmUgYW5kIHdlCgkgICAgIGRvbid0IGNhcmUgYWJvdXQgTmFOcywgaS5lLiBuZWdhdGl2ZSB2YWx1ZXMgb2YgeC4gICovCgkgIGlmIChjb2RlID09IE5FX0VYUFIgfHwgIUhPTk9SX05BTlMgKG1vZGUpKQoJICAgIHJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLAoJCQkJICAgICBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfb25lX25vZGUpLAoJCQkJICAgICBhcmcpOwoKCSAgLyogc3FydCh4KSA+IHkgaXMgdGhlIHNhbWUgYXMgeCA+PSAwLCBpZiB5IGlzIG5lZ2F0aXZlLiAgKi8KCSAgcmV0dXJuIGZvbGQgKGJ1aWxkIChHRV9FWFBSLCB0eXBlLCBhcmcsCgkJCSAgICAgIGJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnKSwgZGNvbnN0MCkpKTsKCX0KICAgICAgZWxzZSBpZiAoY29kZSA9PSBHVF9FWFBSIHx8IGNvZGUgPT0gR0VfRVhQUikKCXsKCSAgUkVBTF9WQUxVRV9UWVBFIGMyOwoKCSAgUkVBTF9BUklUSE1FVElDIChjMiwgTVVMVF9FWFBSLCBjLCBjKTsKCSAgcmVhbF9jb252ZXJ0ICgmYzIsIG1vZGUsICZjMik7CgoJICBpZiAoUkVBTF9WQUxVRV9JU0lORiAoYzIpKQoJICAgIHsKCSAgICAgIC8qIHNxcnQoeCkgPiB5IGlzIHggPT0gK0luZiwgd2hlbiB5IGlzIHZlcnkgbGFyZ2UuICAqLwoJICAgICAgaWYgKEhPTk9SX0lORklOSVRJRVMgKG1vZGUpKQoJCXJldHVybiBmb2xkIChidWlsZCAoRVFfRVhQUiwgdHlwZSwgYXJnLAoJCQkJICAgIGJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnKSwgYzIpKSk7CgoJICAgICAgLyogc3FydCh4KSA+IHkgaXMgYWx3YXlzIGZhbHNlLCB3aGVuIHkgaXMgdmVyeSBsYXJnZQoJCSBhbmQgd2UgZG9uJ3QgY2FyZSBhYm91dCBpbmZpbml0aWVzLiAgKi8KCSAgICAgIHJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLAoJCQkJICAgICAgIGZvbGRfY29udmVydCAodHlwZSwgaW50ZWdlcl96ZXJvX25vZGUpLAoJCQkJICAgICAgIGFyZyk7CgkgICAgfQoKCSAgLyogc3FydCh4KSA+IGMgaXMgdGhlIHNhbWUgYXMgeCA+IGMqYy4gICovCgkgIHJldHVybiBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwgYXJnLAoJCQkgICAgICBidWlsZF9yZWFsIChUUkVFX1RZUEUgKGFyZyksIGMyKSkpOwoJfQogICAgICBlbHNlIGlmIChjb2RlID09IExUX0VYUFIgfHwgY29kZSA9PSBMRV9FWFBSKQoJewoJICBSRUFMX1ZBTFVFX1RZUEUgYzI7CgoJICBSRUFMX0FSSVRITUVUSUMgKGMyLCBNVUxUX0VYUFIsIGMsIGMpOwoJICByZWFsX2NvbnZlcnQgKCZjMiwgbW9kZSwgJmMyKTsKCgkgIGlmIChSRUFMX1ZBTFVFX0lTSU5GIChjMikpCgkgICAgewoJICAgICAgLyogc3FydCh4KSA8IHkgaXMgYWx3YXlzIHRydWUsIHdoZW4geSBpcyBhIHZlcnkgbGFyZ2UKCQkgdmFsdWUgYW5kIHdlIGRvbid0IGNhcmUgYWJvdXQgTmFOcyBvciBJbmZpbml0aWVzLiAgKi8KCSAgICAgIGlmICghIEhPTk9SX05BTlMgKG1vZGUpICYmICEgSE9OT1JfSU5GSU5JVElFUyAobW9kZSkpCgkJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsCgkJCQkJIGZvbGRfY29udmVydCAodHlwZSwgaW50ZWdlcl9vbmVfbm9kZSksCgkJCQkJIGFyZyk7CgoJICAgICAgLyogc3FydCh4KSA8IHkgaXMgeCAhPSArSW5mIHdoZW4geSBpcyB2ZXJ5IGxhcmdlIGFuZCB3ZQoJCSBkb24ndCBjYXJlIGFib3V0IE5hTnMuICAqLwoJICAgICAgaWYgKCEgSE9OT1JfTkFOUyAobW9kZSkpCgkJcmV0dXJuIGZvbGQgKGJ1aWxkIChORV9FWFBSLCB0eXBlLCBhcmcsCgkJCQkgICAgYnVpbGRfcmVhbCAoVFJFRV9UWVBFIChhcmcpLCBjMikpKTsKCgkgICAgICAvKiBzcXJ0KHgpIDwgeSBpcyB4ID49IDAgd2hlbiB5IGlzIHZlcnkgbGFyZ2UgYW5kIHdlCgkJIGRvbid0IGNhcmUgYWJvdXQgSW5maW5pdGllcy4gICovCgkgICAgICBpZiAoISBIT05PUl9JTkZJTklUSUVTIChtb2RlKSkKCQlyZXR1cm4gZm9sZCAoYnVpbGQgKEdFX0VYUFIsIHR5cGUsIGFyZywKCQkJCSAgICBidWlsZF9yZWFsIChUUkVFX1RZUEUgKGFyZyksIGRjb25zdDApKSk7CgoJICAgICAgLyogc3FydCh4KSA8IHkgaXMgeCA+PSAwICYmIHggIT0gK0luZiwgd2hlbiB5IGlzIGxhcmdlLiAgKi8KCSAgICAgIGlmICgoKmxhbmdfaG9va3MuZGVjbHMuZ2xvYmFsX2JpbmRpbmdzX3ApICgpICE9IDAKCQkgIHx8IENPTlRBSU5TX1BMQUNFSE9MREVSX1AgKGFyZykpCgkJcmV0dXJuIE5VTExfVFJFRTsKCgkgICAgICBhcmcgPSBzYXZlX2V4cHIgKGFyZyk7CgkgICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKFRSVVRIX0FORElGX0VYUFIsIHR5cGUsCgkJCQkgIGZvbGQgKGJ1aWxkIChHRV9FWFBSLCB0eXBlLCBhcmcsCgkJCQkJICAgICAgIGJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnKSwKCQkJCQkJCSAgIGRjb25zdDApKSksCgkJCQkgIGZvbGQgKGJ1aWxkIChORV9FWFBSLCB0eXBlLCBhcmcsCgkJCQkJICAgICAgIGJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnKSwKCQkJCQkJCSAgIGMyKSkpKSk7CgkgICAgfQoKCSAgLyogc3FydCh4KSA8IGMgaXMgdGhlIHNhbWUgYXMgeCA8IGMqYywgaWYgd2UgaWdub3JlIE5hTnMuICAqLwoJICBpZiAoISBIT05PUl9OQU5TIChtb2RlKSkKCSAgICByZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIGFyZywKCQkJCWJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnKSwgYzIpKSk7CgoJICAvKiBzcXJ0KHgpIDwgYyBpcyB0aGUgc2FtZSBhcyB4ID49IDAgJiYgeCA8IGMqYy4gICovCgkgIGlmICgoKmxhbmdfaG9va3MuZGVjbHMuZ2xvYmFsX2JpbmRpbmdzX3ApICgpID09IDAKCSAgICAgICYmICEgQ09OVEFJTlNfUExBQ0VIT0xERVJfUCAoYXJnKSkKCSAgICB7CgkgICAgICBhcmcgPSBzYXZlX2V4cHIgKGFyZyk7CgkgICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKFRSVVRIX0FORElGX0VYUFIsIHR5cGUsCgkJCQkgIGZvbGQgKGJ1aWxkIChHRV9FWFBSLCB0eXBlLCBhcmcsCgkJCQkJICAgICAgIGJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnKSwKCQkJCQkJCSAgIGRjb25zdDApKSksCgkJCQkgIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLCBhcmcsCgkJCQkJICAgICAgIGJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnKSwKCQkJCQkJCSAgIGMyKSkpKSk7CgkgICAgfQoJfQogICAgfQoKICByZXR1cm4gTlVMTF9UUkVFOwp9CgovKiBTdWJyb3V0aW5lIG9mIGZvbGQoKSB0aGF0IG9wdGltaXplcyBjb21wYXJpc29ucyBhZ2FpbnN0IEluZmluaXRpZXMsCiAgIGVpdGhlciArSW5mIG9yIC1JbmYuCgogICBDT0RFIGlzIHRoZSBjb21wYXJpc29uIG9wZXJhdG9yOiBFUV9FWFBSLCBORV9FWFBSLCBHVF9FWFBSLCBMVF9FWFBSLAogICBHRV9FWFBSIG9yIExFX0VYUFIuICBUWVBFIGlzIHRoZSB0eXBlIG9mIHRoZSByZXN1bHQgYW5kIEFSRzAgYW5kIEFSRzEKICAgYXJlIHRoZSBvcGVyYW5kcyBvZiB0aGUgY29tcGFyaXNvbi4gIEFSRzEgbXVzdCBiZSBhIFRSRUVfUkVBTF9DU1QuCgogICBUaGUgZnVuY3Rpb24gcmV0dXJucyB0aGUgY29uc3RhbnQgZm9sZGVkIHRyZWUgaWYgYSBzaW1wbGlmaWNhdGlvbgogICBjYW4gYmUgbWFkZSwgYW5kIE5VTExfVFJFRSBvdGhlcndpc2UuICAqLwoKc3RhdGljIHRyZWUKZm9sZF9pbmZfY29tcGFyZSAoZW51bSB0cmVlX2NvZGUgY29kZSwgdHJlZSB0eXBlLCB0cmVlIGFyZzAsIHRyZWUgYXJnMSkKewogIGVudW0gbWFjaGluZV9tb2RlIG1vZGU7CiAgUkVBTF9WQUxVRV9UWVBFIG1heDsKICB0cmVlIHRlbXA7CiAgYm9vbCBuZWc7CgogIG1vZGUgPSBUWVBFX01PREUgKFRSRUVfVFlQRSAoYXJnMCkpOwoKICAvKiBGb3IgbmVnYXRpdmUgaW5maW5pdHkgc3dhcCB0aGUgc2Vuc2Ugb2YgdGhlIGNvbXBhcmlzb24uICAqLwogIG5lZyA9IFJFQUxfVkFMVUVfTkVHQVRJVkUgKFRSRUVfUkVBTF9DU1QgKGFyZzEpKTsKICBpZiAobmVnKQogICAgY29kZSA9IHN3YXBfdHJlZV9jb21wYXJpc29uIChjb2RlKTsKCiAgc3dpdGNoIChjb2RlKQogICAgewogICAgY2FzZSBHVF9FWFBSOgogICAgICAvKiB4ID4gK0luZiBpcyBhbHdheXMgZmFsc2UsIGlmIHdpdGggaWdub3JlIHNOQU5zLiAgKi8KICAgICAgaWYgKEhPTk9SX1NOQU5TIChtb2RlKSkKICAgICAgICByZXR1cm4gTlVMTF9UUkVFOwogICAgICByZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwKCQkJICAgICAgIGZvbGRfY29udmVydCAodHlwZSwgaW50ZWdlcl96ZXJvX25vZGUpLAoJCQkgICAgICAgYXJnMCk7CgogICAgY2FzZSBMRV9FWFBSOgogICAgICAvKiB4IDw9ICtJbmYgaXMgYWx3YXlzIHRydWUsIGlmIHdlIGRvbid0IGNhc2UgYWJvdXQgTmFOcy4gICovCiAgICAgIGlmICghIEhPTk9SX05BTlMgKG1vZGUpKQoJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsCgkJCQkgZm9sZF9jb252ZXJ0ICh0eXBlLCBpbnRlZ2VyX29uZV9ub2RlKSwKCQkJCSBhcmcwKTsKCiAgICAgIC8qIHggPD0gK0luZiBpcyB0aGUgc2FtZSBhcyB4ID09IHgsIGkuZS4gaXNmaW5pdGUoeCkuICAqLwogICAgICBpZiAoKCpsYW5nX2hvb2tzLmRlY2xzLmdsb2JhbF9iaW5kaW5nc19wKSAoKSA9PSAwCgkgICYmICEgQ09OVEFJTlNfUExBQ0VIT0xERVJfUCAoYXJnMCkpCgl7CgkgIGFyZzAgPSBzYXZlX2V4cHIgKGFyZzApOwoJICByZXR1cm4gZm9sZCAoYnVpbGQgKEVRX0VYUFIsIHR5cGUsIGFyZzAsIGFyZzApKTsKCX0KICAgICAgYnJlYWs7CgogICAgY2FzZSBFUV9FWFBSOgogICAgY2FzZSBHRV9FWFBSOgogICAgICAvKiB4ID09ICtJbmYgYW5kIHggPj0gK0luZiBhcmUgYWx3YXlzIGVxdWFsIHRvIHggPiBEQkxfTUFYLiAgKi8KICAgICAgcmVhbF9tYXh2YWwgKCZtYXgsIG5lZywgbW9kZSk7CiAgICAgIHJldHVybiBmb2xkIChidWlsZCAobmVnID8gTFRfRVhQUiA6IEdUX0VYUFIsIHR5cGUsCgkJCSAgYXJnMCwgYnVpbGRfcmVhbCAoVFJFRV9UWVBFIChhcmcwKSwgbWF4KSkpOwoKICAgIGNhc2UgTFRfRVhQUjoKICAgICAgLyogeCA8ICtJbmYgaXMgYWx3YXlzIGVxdWFsIHRvIHggPD0gREJMX01BWC4gICovCiAgICAgIHJlYWxfbWF4dmFsICgmbWF4LCBuZWcsIG1vZGUpOwogICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKG5lZyA/IEdFX0VYUFIgOiBMRV9FWFBSLCB0eXBlLAoJCQkgIGFyZzAsIGJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnMCksIG1heCkpKTsKCiAgICBjYXNlIE5FX0VYUFI6CiAgICAgIC8qIHggIT0gK0luZiBpcyBhbHdheXMgZXF1YWwgdG8gISh4ID4gREJMX01BWCkuICAqLwogICAgICByZWFsX21heHZhbCAoJm1heCwgbmVnLCBtb2RlKTsKICAgICAgaWYgKCEgSE9OT1JfTkFOUyAobW9kZSkpCglyZXR1cm4gZm9sZCAoYnVpbGQgKG5lZyA/IEdFX0VYUFIgOiBMRV9FWFBSLCB0eXBlLAoJCQkgICAgYXJnMCwgYnVpbGRfcmVhbCAoVFJFRV9UWVBFIChhcmcwKSwgbWF4KSkpOwogICAgICB0ZW1wID0gZm9sZCAoYnVpbGQgKG5lZyA/IExUX0VYUFIgOiBHVF9FWFBSLCB0eXBlLAoJCQkgIGFyZzAsIGJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnMCksIG1heCkpKTsKICAgICAgcmV0dXJuIGZvbGQgKGJ1aWxkMSAoVFJVVEhfTk9UX0VYUFIsIHR5cGUsIHRlbXApKTsKCiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICAgIH0KCiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKLyogSWYgQ09ERSB3aXRoIGFyZ3VtZW50cyBBUkcwIGFuZCBBUkcxIHJlcHJlc2VudHMgYSBzaW5nbGUgYml0CiAgIGVxdWFsaXR5L2luZXF1YWxpdHkgdGVzdCwgdGhlbiByZXR1cm4gYSBzaW1wbGlmaWVkIGZvcm0gb2YKICAgdGhlIHRlc3QgdXNpbmcgc2hpZnRzIGFuZCBsb2dpY2FsIG9wZXJhdGlvbnMuICBPdGhlcndpc2UgcmV0dXJuCiAgIE5VTEwuICBUWVBFIGlzIHRoZSBkZXNpcmVkIHJlc3VsdCB0eXBlLiAgKi8KIAp0cmVlCmZvbGRfc2luZ2xlX2JpdF90ZXN0IChlbnVtIHRyZWVfY29kZSBjb2RlLCB0cmVlIGFyZzAsIHRyZWUgYXJnMSwKCQkgICAgICB0cmVlIHJlc3VsdF90eXBlKQp7CiAgLyogSWYgdGhpcyBpcyBhIFRSVVRIX05PVF9FWFBSLCBpdCBtYXkgaGF2ZSBhIHNpbmdsZSBiaXQgdGVzdCBpbnNpZGUKICAgICBvcGVyYW5kIDAuICAqLwogIGlmIChjb2RlID09IFRSVVRIX05PVF9FWFBSKQogICAgewogICAgICBjb2RlID0gVFJFRV9DT0RFIChhcmcwKTsKICAgICAgaWYgKGNvZGUgIT0gTkVfRVhQUiAmJiBjb2RlICE9IEVRX0VYUFIpCglyZXR1cm4gTlVMTF9UUkVFOwoKICAgICAgLyogRXh0cmFjdCB0aGUgYXJndW1lbnRzIG9mIHRoZSBFUS9ORS4gICovCiAgICAgIGFyZzEgPSBUUkVFX09QRVJBTkQgKGFyZzAsIDEpOwogICAgICBhcmcwID0gVFJFRV9PUEVSQU5EIChhcmcwLCAwKTsKCiAgICAgIC8qIFRoaXMgcmVxdWlyZXMgdXMgdG8gaW52ZXJ0IHRoZSBjb2RlLiAgKi8gCiAgICAgIGNvZGUgPSAoY29kZSA9PSBFUV9FWFBSID8gTkVfRVhQUiA6IEVRX0VYUFIpOwogICAgfQoKICAvKiBJZiB0aGlzIGlzIHRlc3RpbmcgYSBzaW5nbGUgYml0LCB3ZSBjYW4gb3B0aW1pemUgdGhlIHRlc3QuICAqLwogIGlmICgoY29kZSA9PSBORV9FWFBSIHx8IGNvZGUgPT0gRVFfRVhQUikKICAgICAgJiYgVFJFRV9DT0RFIChhcmcwKSA9PSBCSVRfQU5EX0VYUFIgJiYgaW50ZWdlcl96ZXJvcCAoYXJnMSkKICAgICAgJiYgaW50ZWdlcl9wb3cycCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkpCiAgICB7CiAgICAgIHRyZWUgaW5uZXIgPSBUUkVFX09QRVJBTkQgKGFyZzAsIDApOwogICAgICB0cmVlIHR5cGUgPSBUUkVFX1RZUEUgKGFyZzApOwogICAgICBpbnQgYml0bnVtID0gdHJlZV9sb2cyIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKTsKICAgICAgZW51bSBtYWNoaW5lX21vZGUgb3BlcmFuZF9tb2RlID0gVFlQRV9NT0RFICh0eXBlKTsKICAgICAgaW50IG9wc191bnNpZ25lZDsKICAgICAgdHJlZSBzaWduZWRfdHlwZSwgdW5zaWduZWRfdHlwZSwgaW50ZXJtZWRpYXRlX3R5cGU7CiAgICAgIHRyZWUgYXJnMDA7CiAgCiAgICAgIC8qIElmIHdlIGhhdmUgKEEgJiBDKSAhPSAwIHdoZXJlIEMgaXMgdGhlIHNpZ24gYml0IG9mIEEsIGNvbnZlcnQKCSB0aGlzIGludG8gQSA8IDAuICBTaW1pbGFybHkgZm9yIChBICYgQykgPT0gMCBpbnRvIEEgPj0gMC4gICovCiAgICAgIGFyZzAwID0gc2lnbl9iaXRfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSk7CiAgICAgIGlmIChhcmcwMCAhPSBOVUxMX1RSRUUKCSAgLyogVGhpcyBpcyBvbmx5IGEgd2luIGlmIGNhc3RpbmcgdG8gYSBzaWduZWQgdHlwZSBpcyBjaGVhcCwKCSAgICAgaS5lLiB3aGVuIGFyZzAwJ3MgdHlwZSBpcyBub3QgYSBwYXJ0aWFsIG1vZGUuICAqLwoJICAmJiBUWVBFX1BSRUNJU0lPTiAoVFJFRV9UWVBFIChhcmcwMCkpCgkgICAgID09IEdFVF9NT0RFX0JJVFNJWkUgKFRZUEVfTU9ERSAoVFJFRV9UWVBFIChhcmcwMCkpKSkKCXsKCSAgdHJlZSBzdHlwZSA9ICgqbGFuZ19ob29rcy50eXBlcy5zaWduZWRfdHlwZSkgKFRSRUVfVFlQRSAoYXJnMDApKTsKCSAgcmV0dXJuIGZvbGQgKGJ1aWxkIChjb2RlID09IEVRX0VYUFIgPyBHRV9FWFBSIDogTFRfRVhQUiwgcmVzdWx0X3R5cGUsCgkJCSAgICAgIGZvbGRfY29udmVydCAoc3R5cGUsIGFyZzAwKSwKCQkJICAgICAgZm9sZF9jb252ZXJ0IChzdHlwZSwgaW50ZWdlcl96ZXJvX25vZGUpKSk7Cgl9CgogICAgICAvKiBPdGhlcndpc2Ugd2UgaGF2ZSAoQSAmIEMpICE9IDAgd2hlcmUgQyBpcyBhIHNpbmdsZSBiaXQsIAoJIGNvbnZlcnQgdGhhdCBpbnRvICgoQSA+PiBDMikgJiAxKS4gIFdoZXJlIEMyID0gbG9nMihDKS4KCSBTaW1pbGFybHkgZm9yIChBICYgQykgPT0gMC4gICovCgogICAgICAvKiBJZiBJTk5FUiBpcyBhIHJpZ2h0IHNoaWZ0IG9mIGEgY29uc3RhbnQgYW5kIGl0IHBsdXMgQklUTlVNIGRvZXMKCSBub3Qgb3ZlcmZsb3csIGFkanVzdCBCSVROVU0gYW5kIElOTkVSLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoaW5uZXIpID09IFJTSElGVF9FWFBSCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChpbm5lciwgMSkpID09IElOVEVHRVJfQ1NUCgkgICYmIFRSRUVfSU5UX0NTVF9ISUdIIChUUkVFX09QRVJBTkQgKGlubmVyLCAxKSkgPT0gMAoJICAmJiBiaXRudW0gPCBUWVBFX1BSRUNJU0lPTiAodHlwZSkKCSAgJiYgMCA+IGNvbXBhcmVfdHJlZV9pbnQgKFRSRUVfT1BFUkFORCAoaW5uZXIsIDEpLAoJCQkJICAgYml0bnVtIC0gVFlQRV9QUkVDSVNJT04gKHR5cGUpKSkKCXsKCSAgYml0bnVtICs9IFRSRUVfSU5UX0NTVF9MT1cgKFRSRUVfT1BFUkFORCAoaW5uZXIsIDEpKTsKCSAgaW5uZXIgPSBUUkVFX09QRVJBTkQgKGlubmVyLCAwKTsKCX0KCiAgICAgIC8qIElmIHdlIGFyZSBnb2luZyB0byBiZSBhYmxlIHRvIG9taXQgdGhlIEFORCBiZWxvdywgd2UgbXVzdCBkbyBvdXIKCSBvcGVyYXRpb25zIGFzIHVuc2lnbmVkLiAgSWYgd2UgbXVzdCB1c2UgdGhlIEFORCwgd2UgaGF2ZSBhIGNob2ljZS4KCSBOb3JtYWxseSB1bnNpZ25lZCBpcyBmYXN0ZXIsIGJ1dCBmb3Igc29tZSBtYWNoaW5lcyBzaWduZWQgaXMuICAqLwojaWZkZWYgTE9BRF9FWFRFTkRfT1AKICAgICAgb3BzX3Vuc2lnbmVkID0gKExPQURfRVhURU5EX09QIChvcGVyYW5kX21vZGUpID09IFNJR05fRVhURU5EID8gMCA6IDEpOwojZWxzZQogICAgICBvcHNfdW5zaWduZWQgPSAxOwojZW5kaWYKCiAgICAgIHNpZ25lZF90eXBlID0gKCpsYW5nX2hvb2tzLnR5cGVzLnR5cGVfZm9yX21vZGUpIChvcGVyYW5kX21vZGUsIDApOwogICAgICB1bnNpZ25lZF90eXBlID0gKCpsYW5nX2hvb2tzLnR5cGVzLnR5cGVfZm9yX21vZGUpIChvcGVyYW5kX21vZGUsIDEpOwogICAgICBpbnRlcm1lZGlhdGVfdHlwZSA9IG9wc191bnNpZ25lZCA/IHVuc2lnbmVkX3R5cGUgOiBzaWduZWRfdHlwZTsKICAgICAgaW5uZXIgPSBmb2xkX2NvbnZlcnQgKGludGVybWVkaWF0ZV90eXBlLCBpbm5lcik7CgogICAgICBpZiAoYml0bnVtICE9IDApCglpbm5lciA9IGJ1aWxkIChSU0hJRlRfRVhQUiwgaW50ZXJtZWRpYXRlX3R5cGUsCgkJICAgICAgIGlubmVyLCBzaXplX2ludCAoYml0bnVtKSk7CgogICAgICBpZiAoY29kZSA9PSBFUV9FWFBSKQoJaW5uZXIgPSBidWlsZCAoQklUX1hPUl9FWFBSLCBpbnRlcm1lZGlhdGVfdHlwZSwKCQkgICAgICAgaW5uZXIsIGludGVnZXJfb25lX25vZGUpOwoKICAgICAgLyogUHV0IHRoZSBBTkQgbGFzdCBzbyBpdCBjYW4gY29tYmluZSB3aXRoIG1vcmUgdGhpbmdzLiAgKi8KICAgICAgaW5uZXIgPSBidWlsZCAoQklUX0FORF9FWFBSLCBpbnRlcm1lZGlhdGVfdHlwZSwKCQkgICAgIGlubmVyLCBpbnRlZ2VyX29uZV9ub2RlKTsKCiAgICAgIC8qIE1ha2Ugc3VyZSB0byByZXR1cm4gdGhlIHByb3BlciB0eXBlLiAgKi8KICAgICAgaW5uZXIgPSBmb2xkX2NvbnZlcnQgKHJlc3VsdF90eXBlLCBpbm5lcik7CgogICAgICByZXR1cm4gaW5uZXI7CiAgICB9CiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKLyogQ2hlY2sgd2hldGhlciB3ZSBhcmUgYWxsb3dlZCB0byByZW9yZGVyIG9wZXJhbmRzIGFyZzAgYW5kIGFyZzEsCiAgIHN1Y2ggdGhhdCB0aGUgZXZhbHVhdGlvbiBvZiBhcmcxIG9jY3VycyBiZWZvcmUgYXJnMC4gICovCgpzdGF0aWMgYm9vbApyZW9yZGVyX29wZXJhbmRzX3AgKHRyZWUgYXJnMCwgdHJlZSBhcmcxKQp7CiAgaWYgKCEgZmxhZ19ldmFsdWF0aW9uX29yZGVyKQogICAgcmV0dXJuIHRydWU7CiAgaWYgKFRSRUVfQ09OU1RBTlQgKGFyZzApIHx8IFRSRUVfQ09OU1RBTlQgKGFyZzEpKQogICAgcmV0dXJuIHRydWU7CiAgcmV0dXJuICEgVFJFRV9TSURFX0VGRkVDVFMgKGFyZzApCgkgJiYgISBUUkVFX1NJREVfRUZGRUNUUyAoYXJnMSk7Cn0KCi8qIFRlc3Qgd2hldGhlciBpdCBpcyBwcmVmZXJhYmxlIHR3byBzd2FwIHR3byBvcGVyYW5kcywgQVJHMCBhbmQKICAgQVJHMSwgZm9yIGV4YW1wbGUgYmVjYXVzZSBBUkcwIGlzIGFuIGludGVnZXIgY29uc3RhbnQgYW5kIEFSRzEKICAgaXNuJ3QuICBJZiBSRU9SREVSIGlzIHRydWUsIG9ubHkgcmVjb21tZW5kIHN3YXBwaW5nIGlmIHdlIGNhbgogICBldmFsdWF0ZSB0aGUgb3BlcmFuZHMgaW4gcmV2ZXJzZSBvcmRlci4gICovCgpzdGF0aWMgYm9vbAp0cmVlX3N3YXBfb3BlcmFuZHNfcCAodHJlZSBhcmcwLCB0cmVlIGFyZzEsIGJvb2wgcmVvcmRlcikKewogIFNUUklQX1NJR05fTk9QUyAoYXJnMCk7CiAgU1RSSVBfU0lHTl9OT1BTIChhcmcxKTsKCiAgaWYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QpCiAgICByZXR1cm4gMDsKICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBJTlRFR0VSX0NTVCkKICAgIHJldHVybiAxOwoKICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBSRUFMX0NTVCkKICAgIHJldHVybiAwOwogIGlmIChUUkVFX0NPREUgKGFyZzApID09IFJFQUxfQ1NUKQogICAgcmV0dXJuIDE7CgogIGlmIChUUkVFX0NPREUgKGFyZzEpID09IENPTVBMRVhfQ1NUKQogICAgcmV0dXJuIDA7CiAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQ09NUExFWF9DU1QpCiAgICByZXR1cm4gMTsKCiAgaWYgKFRSRUVfQ09OU1RBTlQgKGFyZzEpKQogICAgcmV0dXJuIDA7CiAgaWYgKFRSRUVfQ09OU1RBTlQgKGFyZzApKQogICAgcmV0dXJuIDE7CiAgICAKICBpZiAob3B0aW1pemVfc2l6ZSkKICAgIHJldHVybiAwOwoKICBpZiAocmVvcmRlciAmJiBmbGFnX2V2YWx1YXRpb25fb3JkZXIKICAgICAgJiYgKFRSRUVfU0lERV9FRkZFQ1RTIChhcmcwKSB8fCBUUkVFX1NJREVfRUZGRUNUUyAoYXJnMSkpKQogICAgcmV0dXJuIDA7CgogIGlmIChERUNMX1AgKGFyZzEpKQogICAgcmV0dXJuIDA7CiAgaWYgKERFQ0xfUCAoYXJnMCkpCiAgICByZXR1cm4gMTsKCiAgcmV0dXJuIDA7Cn0KCi8qIFBlcmZvcm0gY29uc3RhbnQgZm9sZGluZyBhbmQgcmVsYXRlZCBzaW1wbGlmaWNhdGlvbiBvZiBFWFBSLgogICBUaGUgcmVsYXRlZCBzaW1wbGlmaWNhdGlvbnMgaW5jbHVkZSB4KjEgPT4geCwgeCowID0+IDAsIGV0Yy4sCiAgIGFuZCBhcHBsaWNhdGlvbiBvZiB0aGUgYXNzb2NpYXRpdmUgbGF3LgogICBOT1BfRVhQUiBjb252ZXJzaW9ucyBtYXkgYmUgcmVtb3ZlZCBmcmVlbHkgKGFzIGxvbmcgYXMgd2UKICAgYXJlIGNhcmVmdWwgbm90IHRvIGNoYW5nZSB0aGUgQyB0eXBlIG9mIHRoZSBvdmVyYWxsIGV4cHJlc3Npb24pCiAgIFdlIGNhbm5vdCBzaW1wbGlmeSB0aHJvdWdoIGEgQ09OVkVSVF9FWFBSLCBGSVhfRVhQUiBvciBGTE9BVF9FWFBSLAogICBidXQgd2UgY2FuIGNvbnN0YW50LWZvbGQgdGhlbSBpZiB0aGV5IGhhdmUgY29uc3RhbnQgb3BlcmFuZHMuICAqLwoKI2lmZGVmIEVOQUJMRV9GT0xEX0NIRUNLSU5HCiMgZGVmaW5lIGZvbGQoeCkgZm9sZF8xICh4KQpzdGF0aWMgdHJlZSBmb2xkXzEgKHRyZWUpOwpzdGF0aWMKI2VuZGlmCnRyZWUKZm9sZCAodHJlZSBleHByKQp7CiAgdHJlZSB0ID0gZXhwciwgb3JpZ190OwogIHRyZWUgdDEgPSBOVUxMX1RSRUU7CiAgdHJlZSB0ZW07CiAgdHJlZSB0eXBlID0gVFJFRV9UWVBFIChleHByKTsKICB0cmVlIGFyZzAgPSBOVUxMX1RSRUUsIGFyZzEgPSBOVUxMX1RSRUU7CiAgZW51bSB0cmVlX2NvZGUgY29kZSA9IFRSRUVfQ09ERSAodCk7CiAgaW50IGtpbmQgPSBUUkVFX0NPREVfQ0xBU1MgKGNvZGUpOwogIGludCBpbnZlcnQ7CiAgLyogV0lOUyB3aWxsIGJlIG5vbnplcm8gd2hlbiB0aGUgc3dpdGNoIGlzIGRvbmUKICAgICBpZiBhbGwgb3BlcmFuZHMgYXJlIGNvbnN0YW50LiAgKi8KICBpbnQgd2lucyA9IDE7CgogIC8qIERvbid0IHRyeSB0byBwcm9jZXNzIGFuIFJUTF9FWFBSIHNpbmNlIGl0cyBvcGVyYW5kcyBhcmVuJ3QgdHJlZXMuCiAgICAgTGlrZXdpc2UgZm9yIGEgU0FWRV9FWFBSIHRoYXQncyBhbHJlYWR5IGJlZW4gZXZhbHVhdGVkLiAgKi8KICBpZiAoY29kZSA9PSBSVExfRVhQUiB8fCAoY29kZSA9PSBTQVZFX0VYUFIgJiYgU0FWRV9FWFBSX1JUTCAodCkgIT0gMCkpCiAgICByZXR1cm4gdDsKCiAgLyogUmV0dXJuIHJpZ2h0IGF3YXkgaWYgYSBjb25zdGFudC4gICovCiAgaWYgKGtpbmQgPT0gJ2MnKQogICAgcmV0dXJuIHQ7CgogIG9yaWdfdCA9IHQ7CgogIGlmIChjb2RlID09IE5PUF9FWFBSIHx8IGNvZGUgPT0gRkxPQVRfRVhQUiB8fCBjb2RlID09IENPTlZFUlRfRVhQUikKICAgIHsKICAgICAgdHJlZSBzdWJvcDsKCiAgICAgIC8qIFNwZWNpYWwgY2FzZSBmb3IgY29udmVyc2lvbiBvcHMgdGhhdCBjYW4gaGF2ZSBmaXhlZCBwb2ludCBhcmdzLiAgKi8KICAgICAgYXJnMCA9IFRSRUVfT1BFUkFORCAodCwgMCk7CgogICAgICAvKiBEb24ndCB1c2UgU1RSSVBfTk9QUywgYmVjYXVzZSBzaWduZWRuZXNzIG9mIGFyZ3VtZW50IHR5cGUgbWF0dGVycy4gICovCiAgICAgIGlmIChhcmcwICE9IDApCglTVFJJUF9TSUdOX05PUFMgKGFyZzApOwoKICAgICAgaWYgKGFyZzAgIT0gMCAmJiBUUkVFX0NPREUgKGFyZzApID09IENPTVBMRVhfQ1NUKQoJc3Vib3AgPSBUUkVFX1JFQUxQQVJUIChhcmcwKTsKICAgICAgZWxzZQoJc3Vib3AgPSBhcmcwOwoKICAgICAgaWYgKHN1Ym9wICE9IDAgJiYgVFJFRV9DT0RFIChzdWJvcCkgIT0gSU5URUdFUl9DU1QKCSAgJiYgVFJFRV9DT0RFIChzdWJvcCkgIT0gUkVBTF9DU1QpCgkvKiBOb3RlIHRoYXQgVFJFRV9DT05TVEFOVCBpc24ndCBlbm91Z2g6CgkgICBzdGF0aWMgdmFyIGFkZHJlc3NlcyBhcmUgY29uc3RhbnQgYnV0IHdlIGNhbid0CgkgICBkbyBhcml0aG1ldGljIG9uIHRoZW0uICAqLwoJd2lucyA9IDA7CiAgICB9CiAgZWxzZSBpZiAoSVNfRVhQUl9DT0RFX0NMQVNTIChraW5kKSkKICAgIHsKICAgICAgaW50IGxlbiA9IGZpcnN0X3J0bF9vcCAoY29kZSk7CiAgICAgIGludCBpOwogICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspCgl7CgkgIHRyZWUgb3AgPSBUUkVFX09QRVJBTkQgKHQsIGkpOwoJICB0cmVlIHN1Ym9wOwoKCSAgaWYgKG9wID09IDApCgkgICAgY29udGludWU7CQkvKiBWYWxpZCBmb3IgQ0FMTF9FWFBSLCBhdCBsZWFzdC4gICovCgoJICBpZiAoa2luZCA9PSAnPCcgfHwgY29kZSA9PSBSU0hJRlRfRVhQUikKCSAgICB7CgkgICAgICAvKiBTaWduZWRuZXNzIG1hdHRlcnMgaGVyZS4gIFBlcmhhcHMgd2UgY2FuIHJlZmluZSB0aGlzCgkJIGxhdGVyLiAgKi8KCSAgICAgIFNUUklQX1NJR05fTk9QUyAob3ApOwoJICAgIH0KCSAgZWxzZQoJICAgIC8qIFN0cmlwIGFueSBjb252ZXJzaW9ucyB0aGF0IGRvbid0IGNoYW5nZSB0aGUgbW9kZS4gICovCgkgICAgU1RSSVBfTk9QUyAob3ApOwoKCSAgaWYgKFRSRUVfQ09ERSAob3ApID09IENPTVBMRVhfQ1NUKQoJICAgIHN1Ym9wID0gVFJFRV9SRUFMUEFSVCAob3ApOwoJICBlbHNlCgkgICAgc3Vib3AgPSBvcDsKCgkgIGlmIChUUkVFX0NPREUgKHN1Ym9wKSAhPSBJTlRFR0VSX0NTVAoJICAgICAgJiYgVFJFRV9DT0RFIChzdWJvcCkgIT0gUkVBTF9DU1QpCgkgICAgLyogTm90ZSB0aGF0IFRSRUVfQ09OU1RBTlQgaXNuJ3QgZW5vdWdoOgoJICAgICAgIHN0YXRpYyB2YXIgYWRkcmVzc2VzIGFyZSBjb25zdGFudCBidXQgd2UgY2FuJ3QKCSAgICAgICBkbyBhcml0aG1ldGljIG9uIHRoZW0uICAqLwoJICAgIHdpbnMgPSAwOwoKCSAgaWYgKGkgPT0gMCkKCSAgICBhcmcwID0gb3A7CgkgIGVsc2UgaWYgKGkgPT0gMSkKCSAgICBhcmcxID0gb3A7Cgl9CiAgICB9CgogIC8qIElmIHRoaXMgaXMgYSBjb21tdXRhdGl2ZSBvcGVyYXRpb24sIGFuZCBBUkcwIGlzIGEgY29uc3RhbnQsIG1vdmUgaXQKICAgICB0byBBUkcxIHRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHRlc3RzIGJlbG93LiAgKi8KICBpZiAoKGNvZGUgPT0gUExVU19FWFBSIHx8IGNvZGUgPT0gTVVMVF9FWFBSIHx8IGNvZGUgPT0gTUlOX0VYUFIKICAgICAgIHx8IGNvZGUgPT0gTUFYX0VYUFIgfHwgY29kZSA9PSBCSVRfSU9SX0VYUFIgfHwgY29kZSA9PSBCSVRfWE9SX0VYUFIKICAgICAgIHx8IGNvZGUgPT0gQklUX0FORF9FWFBSKQogICAgICAmJiB0cmVlX3N3YXBfb3BlcmFuZHNfcCAoYXJnMCwgYXJnMSwgdHJ1ZSkpCiAgICByZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIFRSRUVfT1BFUkFORCAodCwgMSksCgkJCVRSRUVfT1BFUkFORCAodCwgMCkpKTsKCiAgLyogTm93IFdJTlMgaXMgc2V0IGFzIGRlc2NyaWJlZCBhYm92ZSwKICAgICBBUkcwIGlzIHRoZSBmaXJzdCBvcGVyYW5kIG9mIEVYUFIsCiAgICAgYW5kIEFSRzEgaXMgdGhlIHNlY29uZCBvcGVyYW5kIChpZiBpdCBoYXMgbW9yZSB0aGFuIG9uZSBvcGVyYW5kKS4KCiAgICAgRmlyc3QgY2hlY2sgZm9yIGNhc2VzIHdoZXJlIGFuIGFyaXRobWV0aWMgb3BlcmF0aW9uIGlzIGFwcGxpZWQgdG8gYQogICAgIGNvbXBvdW5kLCBjb25kaXRpb25hbCwgb3IgY29tcGFyaXNvbiBvcGVyYXRpb24uICBQdXNoIHRoZSBhcml0aG1ldGljCiAgICAgb3BlcmF0aW9uIGluc2lkZSB0aGUgY29tcG91bmQgb3IgY29uZGl0aW9uYWwgdG8gc2VlIGlmIGFueSBmb2xkaW5nCiAgICAgY2FuIHRoZW4gYmUgZG9uZS4gIENvbnZlcnQgY29tcGFyaXNvbiB0byBjb25kaXRpb25hbCBmb3IgdGhpcyBwdXJwb3NlLgogICAgIFRoZSBhbHNvIG9wdGltaXplcyBub24tY29uc3RhbnQgY2FzZXMgdGhhdCB1c2VkIHRvIGJlIGRvbmUgaW4KICAgICBleHBhbmRfZXhwci4KCiAgICAgQmVmb3JlIHdlIGRvIHRoYXQsIHNlZSBpZiB0aGlzIGlzIGEgQklUX0FORF9FWFBSIG9yIGEgQklUX0lPUl9FWFBSLAogICAgIG9uZSBvZiB0aGUgb3BlcmFuZHMgaXMgYSBjb21wYXJpc29uIGFuZCB0aGUgb3RoZXIgaXMgYSBjb21wYXJpc29uLCBhCiAgICAgQklUX0FORF9FWFBSIHdpdGggdGhlIGNvbnN0YW50IDEsIG9yIGEgdHJ1dGggdmFsdWUuICBJbiB0aGF0IGNhc2UsIHRoZQogICAgIGNvZGUgYmVsb3cgd291bGQgbWFrZSB0aGUgZXhwcmVzc2lvbiBtb3JlIGNvbXBsZXguICBDaGFuZ2UgaXQgdG8gYQogICAgIFRSVVRIX3tBTkQsT1J9X0VYUFIuICBMaWtld2lzZSwgY29udmVydCBhIHNpbWlsYXIgTkVfRVhQUiB0bwogICAgIFRSVVRIX1hPUl9FWFBSIGFuZCBhbiBFUV9FWFBSIHRvIHRoZSBpbnZlcnNpb24gb2YgYSBUUlVUSF9YT1JfRVhQUi4gICovCgogIGlmICgoY29kZSA9PSBCSVRfQU5EX0VYUFIgfHwgY29kZSA9PSBCSVRfSU9SX0VYUFIKICAgICAgIHx8IGNvZGUgPT0gRVFfRVhQUiB8fCBjb2RlID09IE5FX0VYUFIpCiAgICAgICYmICgodHJ1dGhfdmFsdWVfcCAoVFJFRV9DT0RFIChhcmcwKSkKCSAgICYmICh0cnV0aF92YWx1ZV9wIChUUkVFX0NPREUgKGFyZzEpKQoJICAgICAgIHx8IChUUkVFX0NPREUgKGFyZzEpID09IEJJVF9BTkRfRVhQUgoJCSAgICYmIGludGVnZXJfb25lcCAoVFJFRV9PUEVSQU5EIChhcmcxLCAxKSkpKSkKCSAgfHwgKHRydXRoX3ZhbHVlX3AgKFRSRUVfQ09ERSAoYXJnMSkpCgkgICAgICAmJiAodHJ1dGhfdmFsdWVfcCAoVFJFRV9DT0RFIChhcmcwKSkKCQkgIHx8IChUUkVFX0NPREUgKGFyZzApID09IEJJVF9BTkRfRVhQUgoJCSAgICAgICYmIGludGVnZXJfb25lcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkpKSkpKQogICAgewogICAgICB0ID0gZm9sZCAoYnVpbGQgKGNvZGUgPT0gQklUX0FORF9FWFBSID8gVFJVVEhfQU5EX0VYUFIKCQkgICAgICAgOiBjb2RlID09IEJJVF9JT1JfRVhQUiA/IFRSVVRIX09SX0VYUFIKCQkgICAgICAgOiBUUlVUSF9YT1JfRVhQUiwKCQkgICAgICAgdHlwZSwgYXJnMCwgYXJnMSkpOwoKICAgICAgaWYgKGNvZGUgPT0gRVFfRVhQUikKCXQgPSBpbnZlcnRfdHJ1dGh2YWx1ZSAodCk7CgogICAgICByZXR1cm4gdDsKICAgIH0KCiAgaWYgKFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgPT0gJzEnKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBDT01QT1VORF9FWFBSKQoJcmV0dXJuIGJ1aWxkIChDT01QT1VORF9FWFBSLCB0eXBlLCBUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCSAgICAgIGZvbGQgKGJ1aWxkMSAoY29kZSwgdHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkpKTsKICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBDT05EX0VYUFIpCgl7CgkgIHRyZWUgYXJnMDEgPSBUUkVFX09QRVJBTkQgKGFyZzAsIDEpOwoJICB0cmVlIGFyZzAyID0gVFJFRV9PUEVSQU5EIChhcmcwLCAyKTsKCSAgaWYgKCEgVk9JRF9UWVBFX1AgKFRSRUVfVFlQRSAoYXJnMDEpKSkKCSAgICBhcmcwMSA9IGZvbGQgKGJ1aWxkMSAoY29kZSwgdHlwZSwgYXJnMDEpKTsKCSAgaWYgKCEgVk9JRF9UWVBFX1AgKFRSRUVfVFlQRSAoYXJnMDIpKSkKCSAgICBhcmcwMiA9IGZvbGQgKGJ1aWxkMSAoY29kZSwgdHlwZSwgYXJnMDIpKTsKCSAgdCA9IGZvbGQgKGJ1aWxkIChDT05EX0VYUFIsIHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksCgkJCSAgIGFyZzAxLCBhcmcwMikpOwoKCSAgLyogSWYgdGhpcyB3YXMgYSBjb252ZXJzaW9uLCBhbmQgYWxsIHdlIGRpZCB3YXMgdG8gbW92ZSBpbnRvCgkgICAgIGluc2lkZSB0aGUgQ09ORF9FWFBSLCBicmluZyBpdCBiYWNrIG91dC4gIEJ1dCBsZWF2ZSBpdCBpZgoJICAgICBpdCBpcyBhIGNvbnZlcnNpb24gZnJvbSBpbnRlZ2VyIHRvIGludGVnZXIgYW5kIHRoZQoJICAgICByZXN1bHQgcHJlY2lzaW9uIGlzIG5vIHdpZGVyIHRoYW4gYSB3b3JkIHNpbmNlIHN1Y2ggYQoJICAgICBjb252ZXJzaW9uIGlzIGNoZWFwIGFuZCBtYXkgYmUgb3B0aW1pemVkIGF3YXkgYnkgY29tYmluZSwKCSAgICAgd2hpbGUgaXQgY291bGRuJ3QgaWYgaXQgd2VyZSBvdXRzaWRlIHRoZSBDT05EX0VYUFIuICBUaGVuIHJldHVybgoJICAgICBzbyB3ZSBkb24ndCBnZXQgaW50byBhbiBpbmZpbml0ZSByZWN1cnNpb24gbG9vcCB0YWtpbmcgdGhlCgkgICAgIGNvbnZlcnNpb24gb3V0IGFuZCB0aGVuIGJhY2sgaW4uICAqLwoKCSAgaWYgKChjb2RlID09IE5PUF9FWFBSIHx8IGNvZGUgPT0gQ09OVkVSVF9FWFBSCgkgICAgICAgfHwgY29kZSA9PSBOT05fTFZBTFVFX0VYUFIpCgkgICAgICAmJiBUUkVFX0NPREUgKHQpID09IENPTkRfRVhQUgoJICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHQsIDEpKSA9PSBjb2RlCgkgICAgICAmJiBUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAodCwgMikpID09IGNvZGUKCSAgICAgICYmICEgVk9JRF9UWVBFX1AgKFRSRUVfT1BFUkFORCAodCwgMSkpCgkgICAgICAmJiAhIFZPSURfVFlQRV9QIChUUkVFX09QRVJBTkQgKHQsIDIpKQoJICAgICAgJiYgKFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDEpLCAwKSkKCQkgID09IFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDIpLCAwKSkpCgkgICAgICAmJiAhIChJTlRFR1JBTF9UWVBFX1AgKFRSRUVfVFlQRSAodCkpCgkJICAgICYmIChJTlRFR1JBTF9UWVBFX1AKCQkJKFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDEpLCAwKSkpKQoJCSAgICAmJiBUWVBFX1BSRUNJU0lPTiAoVFJFRV9UWVBFICh0KSkgPD0gQklUU19QRVJfV09SRCkpCgkgICAgdCA9IGJ1aWxkMSAoY29kZSwgdHlwZSwKCQkJYnVpbGQgKENPTkRfRVhQUiwKCQkJICAgICAgIFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5ECgkJCQkJICAoVFJFRV9PUEVSQU5EICh0LCAxKSwgMCkpLAoJCQkgICAgICAgVFJFRV9PUEVSQU5EICh0LCAwKSwKCQkJICAgICAgIFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh0LCAxKSwgMCksCgkJCSAgICAgICBUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAodCwgMiksIDApKSk7CgkgIHJldHVybiB0OwoJfQogICAgICBlbHNlIGlmIChUUkVFX0NPREVfQ0xBU1MgKFRSRUVfQ09ERSAoYXJnMCkpID09ICc8JykKCXJldHVybiBmb2xkIChidWlsZCAoQ09ORF9FWFBSLCB0eXBlLCBhcmcwLAoJCQkgICAgZm9sZCAoYnVpbGQxIChjb2RlLCB0eXBlLCBpbnRlZ2VyX29uZV9ub2RlKSksCgkJCSAgICBmb2xkIChidWlsZDEgKGNvZGUsIHR5cGUsIGludGVnZXJfemVyb19ub2RlKSkpKTsKICAgfQogIGVsc2UgaWYgKFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgPT0gJzwnCgkgICAmJiBUUkVFX0NPREUgKGFyZzApID09IENPTVBPVU5EX0VYUFIpCiAgICByZXR1cm4gYnVpbGQgKENPTVBPVU5EX0VYUFIsIHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksCgkJICBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwgYXJnMSkpKTsKICBlbHNlIGlmIChUUkVFX0NPREVfQ0xBU1MgKGNvZGUpID09ICc8JwoJICAgJiYgVFJFRV9DT0RFIChhcmcxKSA9PSBDT01QT1VORF9FWFBSKQogICAgcmV0dXJuIGJ1aWxkIChDT01QT1VORF9FWFBSLCB0eXBlLCBUUkVFX09QRVJBTkQgKGFyZzEsIDApLAoJCSAgZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIGFyZzAsIFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpKSk7CiAgZWxzZSBpZiAoVFJFRV9DT0RFX0NMQVNTIChjb2RlKSA9PSAnMicKCSAgIHx8IFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgPT0gJzwnKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBDT01QT1VORF9FWFBSCgkgICYmICEgVFJFRV9TSURFX0VGRkVDVFMgKFRSRUVfT1BFUkFORCAoYXJnMSwgMCkpCgkgICYmICEgVFJFRV9TSURFX0VGRkVDVFMgKGFyZzApKQoJcmV0dXJuIGJ1aWxkIChDT01QT1VORF9FWFBSLCB0eXBlLCBUUkVFX09QRVJBTkQgKGFyZzEsIDApLAoJCSAgICAgIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLAoJCQkJICAgYXJnMCwgVFJFRV9PUEVSQU5EIChhcmcxLCAxKSkpKTsKICAgICAgZWxzZSBpZiAoKFRSRUVfQ09ERSAoYXJnMSkgPT0gQ09ORF9FWFBSCgkJfHwgKFRSRUVfQ09ERV9DTEFTUyAoVFJFRV9DT0RFIChhcmcxKSkgPT0gJzwnCgkJICAgICYmIFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgIT0gJzwnKSkKCSAgICAgICAmJiAoVFJFRV9DT0RFIChhcmcwKSAhPSBDT05EX0VYUFIKCQkgICB8fCBjb3VudF9jb25kIChhcmcwLCAyNSkgKyBjb3VudF9jb25kIChhcmcxLCAyNSkgPD0gMjUpCgkgICAgICAgJiYgKCEgVFJFRV9TSURFX0VGRkVDVFMgKGFyZzApCgkJICAgfHwgKCgqbGFuZ19ob29rcy5kZWNscy5nbG9iYWxfYmluZGluZ3NfcCkgKCkgPT0gMAoJCSAgICAgICAmJiAhIENPTlRBSU5TX1BMQUNFSE9MREVSX1AgKGFyZzApKSkpCglyZXR1cm4KCSAgZm9sZF9iaW5hcnlfb3Bfd2l0aF9jb25kaXRpb25hbF9hcmcgKGNvZGUsIHR5cGUsIGFyZzEsIGFyZzAsCgkJCQkJICAgICAgIC8qY29uZF9maXJzdF9wPSovMCk7CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQ09NUE9VTkRfRVhQUikKCXJldHVybiBidWlsZCAoQ09NUE9VTkRfRVhQUiwgdHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwKCQkgICAgICBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwgYXJnMSkpKTsKICAgICAgZWxzZSBpZiAoKFRSRUVfQ09ERSAoYXJnMCkgPT0gQ09ORF9FWFBSCgkJfHwgKFRSRUVfQ09ERV9DTEFTUyAoVFJFRV9DT0RFIChhcmcwKSkgPT0gJzwnCgkJICAgICYmIFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgIT0gJzwnKSkKCSAgICAgICAmJiAoVFJFRV9DT0RFIChhcmcxKSAhPSBDT05EX0VYUFIKCQkgICB8fCBjb3VudF9jb25kIChhcmcwLCAyNSkgKyBjb3VudF9jb25kIChhcmcxLCAyNSkgPD0gMjUpCgkgICAgICAgJiYgKCEgVFJFRV9TSURFX0VGRkVDVFMgKGFyZzEpCgkJICAgfHwgKCgqbGFuZ19ob29rcy5kZWNscy5nbG9iYWxfYmluZGluZ3NfcCkgKCkgPT0gMAoJCSAgICAgICAmJiAhIENPTlRBSU5TX1BMQUNFSE9MREVSX1AgKGFyZzEpKSkpCglyZXR1cm4KCSAgZm9sZF9iaW5hcnlfb3Bfd2l0aF9jb25kaXRpb25hbF9hcmcgKGNvZGUsIHR5cGUsIGFyZzAsIGFyZzEsCgkJCQkJICAgICAgIC8qY29uZF9maXJzdF9wPSovMSk7CiAgICB9CgogIHN3aXRjaCAoY29kZSkKICAgIHsKICAgIGNhc2UgSU5URUdFUl9DU1Q6CiAgICBjYXNlIFJFQUxfQ1NUOgogICAgY2FzZSBWRUNUT1JfQ1NUOgogICAgY2FzZSBTVFJJTkdfQ1NUOgogICAgY2FzZSBDT01QTEVYX0NTVDoKICAgIGNhc2UgQ09OU1RSVUNUT1I6CiAgICAgIHJldHVybiB0OwoKICAgIGNhc2UgQ09OU1RfREVDTDoKICAgICAgcmV0dXJuIGZvbGQgKERFQ0xfSU5JVElBTCAodCkpOwoKICAgIGNhc2UgTk9QX0VYUFI6CiAgICBjYXNlIEZMT0FUX0VYUFI6CiAgICBjYXNlIENPTlZFUlRfRVhQUjoKICAgIGNhc2UgRklYX1RSVU5DX0VYUFI6CiAgICAgIC8qIE90aGVyIGtpbmRzIG9mIEZJWCBhcmUgbm90IGhhbmRsZWQgcHJvcGVybHkgYnkgZm9sZF9jb252ZXJ0LiAgKi8KCiAgICAgIGlmIChUUkVFX1RZUEUgKFRSRUVfT1BFUkFORCAodCwgMCkpID09IFRSRUVfVFlQRSAodCkpCglyZXR1cm4gVFJFRV9PUEVSQU5EICh0LCAwKTsKCiAgICAgIC8qIEhhbmRsZSBjYXNlcyBvZiB0d28gY29udmVyc2lvbnMgaW4gYSByb3cuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHQsIDApKSA9PSBOT1BfRVhQUgoJICB8fCBUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAodCwgMCkpID09IENPTlZFUlRfRVhQUikKCXsKCSAgdHJlZSBpbnNpZGVfdHlwZSA9IFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDApLCAwKSk7CgkgIHRyZWUgaW50ZXJfdHlwZSA9IFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EICh0LCAwKSk7CgkgIHRyZWUgZmluYWxfdHlwZSA9IFRSRUVfVFlQRSAodCk7CgkgIGludCBpbnNpZGVfaW50ID0gSU5URUdSQUxfVFlQRV9QIChpbnNpZGVfdHlwZSk7CgkgIGludCBpbnNpZGVfcHRyID0gUE9JTlRFUl9UWVBFX1AgKGluc2lkZV90eXBlKTsKCSAgaW50IGluc2lkZV9mbG9hdCA9IEZMT0FUX1RZUEVfUCAoaW5zaWRlX3R5cGUpOwoJICB1bnNpZ25lZCBpbnQgaW5zaWRlX3ByZWMgPSBUWVBFX1BSRUNJU0lPTiAoaW5zaWRlX3R5cGUpOwoJICBpbnQgaW5zaWRlX3Vuc2lnbmVkcCA9IFRSRUVfVU5TSUdORUQgKGluc2lkZV90eXBlKTsKCSAgaW50IGludGVyX2ludCA9IElOVEVHUkFMX1RZUEVfUCAoaW50ZXJfdHlwZSk7CgkgIGludCBpbnRlcl9wdHIgPSBQT0lOVEVSX1RZUEVfUCAoaW50ZXJfdHlwZSk7CgkgIGludCBpbnRlcl9mbG9hdCA9IEZMT0FUX1RZUEVfUCAoaW50ZXJfdHlwZSk7CgkgIHVuc2lnbmVkIGludCBpbnRlcl9wcmVjID0gVFlQRV9QUkVDSVNJT04gKGludGVyX3R5cGUpOwoJICBpbnQgaW50ZXJfdW5zaWduZWRwID0gVFJFRV9VTlNJR05FRCAoaW50ZXJfdHlwZSk7CgkgIGludCBmaW5hbF9pbnQgPSBJTlRFR1JBTF9UWVBFX1AgKGZpbmFsX3R5cGUpOwoJICBpbnQgZmluYWxfcHRyID0gUE9JTlRFUl9UWVBFX1AgKGZpbmFsX3R5cGUpOwoJICBpbnQgZmluYWxfZmxvYXQgPSBGTE9BVF9UWVBFX1AgKGZpbmFsX3R5cGUpOwoJICB1bnNpZ25lZCBpbnQgZmluYWxfcHJlYyA9IFRZUEVfUFJFQ0lTSU9OIChmaW5hbF90eXBlKTsKCSAgaW50IGZpbmFsX3Vuc2lnbmVkcCA9IFRSRUVfVU5TSUdORUQgKGZpbmFsX3R5cGUpOwoKCSAgLyogSW4gYWRkaXRpb24gdG8gdGhlIGNhc2VzIG9mIHR3byBjb252ZXJzaW9ucyBpbiBhIHJvdwoJICAgICBoYW5kbGVkIGJlbG93LCBpZiB3ZSBhcmUgY29udmVydGluZyBzb21ldGhpbmcgdG8gaXRzIG93bgoJICAgICB0eXBlIHZpYSBhbiBvYmplY3Qgb2YgaWRlbnRpY2FsIG9yIHdpZGVyIHByZWNpc2lvbiwgbmVpdGhlcgoJICAgICBjb252ZXJzaW9uIGlzIG5lZWRlZC4gICovCgkgIGlmIChUWVBFX01BSU5fVkFSSUFOVCAoaW5zaWRlX3R5cGUpID09IFRZUEVfTUFJTl9WQVJJQU5UIChmaW5hbF90eXBlKQoJICAgICAgJiYgKChpbnRlcl9pbnQgJiYgZmluYWxfaW50KSB8fCAoaW50ZXJfZmxvYXQgJiYgZmluYWxfZmxvYXQpKQoJICAgICAgJiYgaW50ZXJfcHJlYyA+PSBmaW5hbF9wcmVjKQoJICAgIHJldHVybiBmb2xkIChidWlsZDEgKGNvZGUsIGZpbmFsX3R5cGUsCgkJCQkgVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDApLCAwKSkpOwoKCSAgLyogTGlrZXdpc2UsIGlmIHRoZSBpbnRlcm1lZGlhdGUgYW5kIGZpbmFsIHR5cGVzIGFyZSBlaXRoZXIgYm90aAoJICAgICBmbG9hdCBvciBib3RoIGludGVnZXIsIHdlIGRvbid0IG5lZWQgdGhlIG1pZGRsZSBjb252ZXJzaW9uIGlmCgkgICAgIGl0IGlzIHdpZGVyIHRoYW4gdGhlIGZpbmFsIHR5cGUgYW5kIGRvZXNuJ3QgY2hhbmdlIHRoZSBzaWduZWRuZXNzCgkgICAgIChmb3IgaW50ZWdlcnMpLiAgQXZvaWQgdGhpcyBpZiB0aGUgZmluYWwgdHlwZSBpcyBhIHBvaW50ZXIKCSAgICAgc2luY2UgdGhlbiB3ZSBzb21ldGltZXMgbmVlZCB0aGUgaW5uZXIgY29udmVyc2lvbi4gIExpa2V3aXNlIGlmCgkgICAgIHRoZSBvdXRlciBoYXMgYSBwcmVjaXNpb24gbm90IGVxdWFsIHRvIHRoZSBzaXplIG9mIGl0cyBtb2RlLiAgKi8KCSAgaWYgKCgoKGludGVyX2ludCB8fCBpbnRlcl9wdHIpICYmIChpbnNpZGVfaW50IHx8IGluc2lkZV9wdHIpKQoJICAgICAgIHx8IChpbnRlcl9mbG9hdCAmJiBpbnNpZGVfZmxvYXQpKQoJICAgICAgJiYgaW50ZXJfcHJlYyA+PSBpbnNpZGVfcHJlYwoJICAgICAgJiYgKGludGVyX2Zsb2F0IHx8IGludGVyX3Vuc2lnbmVkcCA9PSBpbnNpZGVfdW5zaWduZWRwKQoJICAgICAgJiYgISAoZmluYWxfcHJlYyAhPSBHRVRfTU9ERV9CSVRTSVpFIChUWVBFX01PREUgKGZpbmFsX3R5cGUpKQoJCSAgICAmJiBUWVBFX01PREUgKGZpbmFsX3R5cGUpID09IFRZUEVfTU9ERSAoaW50ZXJfdHlwZSkpCgkgICAgICAmJiAhIGZpbmFsX3B0cikKCSAgICByZXR1cm4gZm9sZCAoYnVpbGQxIChjb2RlLCBmaW5hbF90eXBlLAoJCQkJIFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh0LCAwKSwgMCkpKTsKCgkgIC8qIElmIHdlIGhhdmUgYSBzaWduLWV4dGVuc2lvbiBvZiBhIHplcm8tZXh0ZW5kZWQgdmFsdWUsIHdlIGNhbgoJICAgICByZXBsYWNlIHRoYXQgYnkgYSBzaW5nbGUgemVyby1leHRlbnNpb24uICAqLwoJICBpZiAoaW5zaWRlX2ludCAmJiBpbnRlcl9pbnQgJiYgZmluYWxfaW50CgkgICAgICAmJiBpbnNpZGVfcHJlYyA8IGludGVyX3ByZWMgJiYgaW50ZXJfcHJlYyA8IGZpbmFsX3ByZWMKCSAgICAgICYmIGluc2lkZV91bnNpZ25lZHAgJiYgIWludGVyX3Vuc2lnbmVkcCkKCSAgICByZXR1cm4gZm9sZCAoYnVpbGQxIChjb2RlLCBmaW5hbF90eXBlLAoJCQkJIFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh0LCAwKSwgMCkpKTsKCgkgIC8qIFR3byBjb252ZXJzaW9ucyBpbiBhIHJvdyBhcmUgbm90IG5lZWRlZCB1bmxlc3M6CgkgICAgIC0gc29tZSBjb252ZXJzaW9uIGlzIGZsb2F0aW5nLXBvaW50IChvdmVyc3RyaWN0IGZvciBub3cpLCBvcgoJICAgICAtIHRoZSBpbnRlcm1lZGlhdGUgdHlwZSBpcyBuYXJyb3dlciB0aGFuIGJvdGggaW5pdGlhbCBhbmQKCSAgICAgICBmaW5hbCwgb3IKCSAgICAgLSB0aGUgaW50ZXJtZWRpYXRlIHR5cGUgYW5kIGlubmVybW9zdCB0eXBlIGRpZmZlciBpbiBzaWduZWRuZXNzLAoJICAgICAgIGFuZCB0aGUgb3V0ZXJtb3N0IHR5cGUgaXMgd2lkZXIgdGhhbiB0aGUgaW50ZXJtZWRpYXRlLCBvcgoJICAgICAtIHRoZSBpbml0aWFsIHR5cGUgaXMgYSBwb2ludGVyIHR5cGUgYW5kIHRoZSBwcmVjaXNpb25zIG9mIHRoZQoJICAgICAgIGludGVybWVkaWF0ZSBhbmQgZmluYWwgdHlwZXMgZGlmZmVyLCBvcgoJICAgICAtIHRoZSBmaW5hbCB0eXBlIGlzIGEgcG9pbnRlciB0eXBlIGFuZCB0aGUgcHJlY2lzaW9ucyBvZiB0aGUKCSAgICAgICBpbml0aWFsIGFuZCBpbnRlcm1lZGlhdGUgdHlwZXMgZGlmZmVyLiAgKi8KCSAgaWYgKCEgaW5zaWRlX2Zsb2F0ICYmICEgaW50ZXJfZmxvYXQgJiYgISBmaW5hbF9mbG9hdAoJICAgICAgJiYgKGludGVyX3ByZWMgPiBpbnNpZGVfcHJlYyB8fCBpbnRlcl9wcmVjID4gZmluYWxfcHJlYykKCSAgICAgICYmICEgKGluc2lkZV9pbnQgJiYgaW50ZXJfaW50CgkJICAgICYmIGludGVyX3Vuc2lnbmVkcCAhPSBpbnNpZGVfdW5zaWduZWRwCgkJICAgICYmIGludGVyX3ByZWMgPCBmaW5hbF9wcmVjKQoJICAgICAgJiYgKChpbnRlcl91bnNpZ25lZHAgJiYgaW50ZXJfcHJlYyA+IGluc2lkZV9wcmVjKQoJCSAgPT0gKGZpbmFsX3Vuc2lnbmVkcCAmJiBmaW5hbF9wcmVjID4gaW50ZXJfcHJlYykpCgkgICAgICAmJiAhIChpbnNpZGVfcHRyICYmIGludGVyX3ByZWMgIT0gZmluYWxfcHJlYykKCSAgICAgICYmICEgKGZpbmFsX3B0ciAmJiBpbnNpZGVfcHJlYyAhPSBpbnRlcl9wcmVjKQoJICAgICAgJiYgISAoZmluYWxfcHJlYyAhPSBHRVRfTU9ERV9CSVRTSVpFIChUWVBFX01PREUgKGZpbmFsX3R5cGUpKQoJCSAgICAmJiBUWVBFX01PREUgKGZpbmFsX3R5cGUpID09IFRZUEVfTU9ERSAoaW50ZXJfdHlwZSkpCgkgICAgICAmJiAhIGZpbmFsX3B0cikKCSAgICByZXR1cm4gZm9sZCAoYnVpbGQxIChjb2RlLCBmaW5hbF90eXBlLAoJCQkJIFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh0LCAwKSwgMCkpKTsKCX0KCiAgICAgIGlmIChUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAodCwgMCkpID09IE1PRElGWV9FWFBSCgkgICYmIFRSRUVfQ09OU1RBTlQgKFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh0LCAwKSwgMSkpCgkgIC8qIERldGVjdCBhc3NpZ25pbmcgYSBiaXRmaWVsZC4gICovCgkgICYmICEoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAodCwgMCksIDApKSA9PSBDT01QT05FTlRfUkVGCgkgICAgICAgJiYgREVDTF9CSVRfRklFTEQgKFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDApLCAwKSwgMSkpKSkKCXsKCSAgLyogRG9uJ3QgbGVhdmUgYW4gYXNzaWdubWVudCBpbnNpZGUgYSBjb252ZXJzaW9uCgkgICAgIHVubGVzcyBhc3NpZ25pbmcgYSBiaXRmaWVsZC4gICovCgkgIHRyZWUgcHJldiA9IFRSRUVfT1BFUkFORCAodCwgMCk7CgkgIGlmICh0ID09IG9yaWdfdCkKCSAgICB0ID0gY29weV9ub2RlICh0KTsKCSAgVFJFRV9PUEVSQU5EICh0LCAwKSA9IFRSRUVfT1BFUkFORCAocHJldiwgMSk7CgkgIC8qIEZpcnN0IGRvIHRoZSBhc3NpZ25tZW50LCB0aGVuIHJldHVybiBjb252ZXJ0ZWQgY29uc3RhbnQuICAqLwoJICB0ID0gYnVpbGQgKENPTVBPVU5EX0VYUFIsIFRSRUVfVFlQRSAodCksIHByZXYsIGZvbGQgKHQpKTsKCSAgVFJFRV9OT19VTlVTRURfV0FSTklORyAodCkgPSAxOwoJICBUUkVFX1VTRUQgKHQpID0gMTsKCSAgcmV0dXJuIHQ7Cgl9CgogICAgICAvKiBDb252ZXJ0IChUKSh4ICYgYykgaW50byAoVCl4ICYgKFQpYywgaWYgYyBpcyBhbiBpbnRlZ2VyCgkgY29uc3RhbnRzIChpZiB4IGhhcyBzaWduZWQgdHlwZSwgdGhlIHNpZ24gYml0IGNhbm5vdCBiZSBzZXQKCSBpbiBjKS4gIFRoaXMgZm9sZHMgZXh0ZW5zaW9uIGludG8gdGhlIEJJVF9BTkRfRVhQUi4gICovCiAgICAgIGlmIChJTlRFR1JBTF9UWVBFX1AgKFRSRUVfVFlQRSAodCkpCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9UWVBFICh0KSkgIT0gQk9PTEVBTl9UWVBFCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EICh0LCAwKSkgPT0gQklUX0FORF9FWFBSCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDApLCAxKSkgPT0gSU5URUdFUl9DU1QpCgl7CgkgIHRyZWUgYW5kID0gVFJFRV9PUEVSQU5EICh0LCAwKTsKCSAgdHJlZSBhbmQwID0gVFJFRV9PUEVSQU5EIChhbmQsIDApLCBhbmQxID0gVFJFRV9PUEVSQU5EIChhbmQsIDEpOwoJICBpbnQgY2hhbmdlID0gMDsKCgkgIGlmIChUUkVFX1VOU0lHTkVEIChUUkVFX1RZUEUgKGFuZCkpCgkgICAgICB8fCAoVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAodCkpCgkJICA8PSBUWVBFX1BSRUNJU0lPTiAoVFJFRV9UWVBFIChhbmQpKSkpCgkgICAgY2hhbmdlID0gMTsKCSAgZWxzZSBpZiAoVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAoYW5kMSkpCgkJICAgPD0gSE9TVF9CSVRTX1BFUl9XSURFX0lOVAoJCSAgICYmIGhvc3RfaW50ZWdlcnAgKGFuZDEsIDEpKQoJICAgIHsKCSAgICAgIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgY3N0OwoKCSAgICAgIGNzdCA9IHRyZWVfbG93X2NzdCAoYW5kMSwgMSk7CgkgICAgICBjc3QgJj0gKEhPU1RfV0lERV9JTlQpIC0xCgkJICAgICA8PCAoVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAoYW5kMSkpIC0gMSk7CgkgICAgICBjaGFuZ2UgPSAoY3N0ID09IDApOwojaWZkZWYgTE9BRF9FWFRFTkRfT1AKCSAgICAgIGlmIChjaGFuZ2UKCQkgICYmIChMT0FEX0VYVEVORF9PUCAoVFlQRV9NT0RFIChUUkVFX1RZUEUgKGFuZDApKSkKCQkgICAgICA9PSBaRVJPX0VYVEVORCkpCgkJewoJCSAgdHJlZSB1bnMgPSAoKmxhbmdfaG9va3MudHlwZXMudW5zaWduZWRfdHlwZSkgKFRSRUVfVFlQRSAoYW5kMCkpOwoJCSAgYW5kMCA9IGZvbGRfY29udmVydCAodW5zLCBhbmQwKTsKCQkgIGFuZDEgPSBmb2xkX2NvbnZlcnQgKHVucywgYW5kMSk7CgkJfQojZW5kaWYKCSAgICB9CgkgIGlmIChjaGFuZ2UpCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChCSVRfQU5EX0VYUFIsIFRSRUVfVFlQRSAodCksCgkJCQlmb2xkX2NvbnZlcnQgKFRSRUVfVFlQRSAodCksIGFuZDApLAoJCQkJZm9sZF9jb252ZXJ0IChUUkVFX1RZUEUgKHQpLCBhbmQxKSkpOwoJfQoKICAgICAgdGVtID0gZm9sZF9jb252ZXJ0X2NvbnN0IChjb2RlLCBUUkVFX1RZUEUgKHQpLCBhcmcwKTsKICAgICAgcmV0dXJuIHRlbSA/IHRlbSA6IHQ7CgogICAgY2FzZSBWSUVXX0NPTlZFUlRfRVhQUjoKICAgICAgaWYgKFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EICh0LCAwKSkgPT0gVklFV19DT05WRVJUX0VYUFIpCglyZXR1cm4gYnVpbGQxIChWSUVXX0NPTlZFUlRfRVhQUiwgdHlwZSwKCQkgICAgICAgVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDApLCAwKSk7CiAgICAgIHJldHVybiB0OwoKICAgIGNhc2UgQ09NUE9ORU5UX1JFRjoKICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQ09OU1RSVUNUT1IKCSAgJiYgISB0eXBlX2NvbnRhaW5zX3BsYWNlaG9sZGVyX3AgKFRSRUVfVFlQRSAoYXJnMCkpKQoJewoJICB0cmVlIG0gPSBwdXJwb3NlX21lbWJlciAoYXJnMSwgQ09OU1RSVUNUT1JfRUxUUyAoYXJnMCkpOwoJICBpZiAobSkKCSAgICB0ID0gVFJFRV9WQUxVRSAobSk7Cgl9CiAgICAgIHJldHVybiB0OwoKICAgIGNhc2UgUkFOR0VfRVhQUjoKICAgICAgaWYgKFRSRUVfQ09OU1RBTlQgKHQpICE9IHdpbnMpCgl7CgkgIGlmICh0ID09IG9yaWdfdCkKCSAgICB0ID0gY29weV9ub2RlICh0KTsKCSAgVFJFRV9DT05TVEFOVCAodCkgPSB3aW5zOwoJfQogICAgICByZXR1cm4gdDsKCiAgICBjYXNlIE5FR0FURV9FWFBSOgogICAgICBpZiAobmVnYXRlX2V4cHJfcCAoYXJnMCkpCglyZXR1cm4gZm9sZF9jb252ZXJ0ICh0eXBlLCBuZWdhdGVfZXhwciAoYXJnMCkpOwogICAgICByZXR1cm4gdDsKCiAgICBjYXNlIEFCU19FWFBSOgogICAgICBpZiAod2lucykKCXsKCSAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gSU5URUdFUl9DU1QpCgkgICAgewoJICAgICAgLyogSWYgdGhlIHZhbHVlIGlzIHVuc2lnbmVkLCB0aGVuIHRoZSBhYnNvbHV0ZSB2YWx1ZSBpcwoJCSB0aGUgc2FtZSBhcyB0aGUgb3JkaW5hcnkgdmFsdWUuICAqLwoJICAgICAgaWYgKFRSRUVfVU5TSUdORUQgKHR5cGUpKQoJCXJldHVybiBhcmcwOwoJICAgICAgLyogU2ltaWxhcmx5LCBpZiB0aGUgdmFsdWUgaXMgbm9uLW5lZ2F0aXZlLiAgKi8KCSAgICAgIGVsc2UgaWYgKElOVF9DU1RfTFQgKGludGVnZXJfbWludXNfb25lX25vZGUsIGFyZzApKQoJCXJldHVybiBhcmcwOwoJICAgICAgLyogSWYgdGhlIHZhbHVlIGlzIG5lZ2F0aXZlLCB0aGVuIHRoZSBhYnNvbHV0ZSB2YWx1ZSBpcwoJCSBpdHMgbmVnYXRpb24uICAqLwoJICAgICAgZWxzZQoJCXsKCQkgIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgbG93OwoJCSAgSE9TVF9XSURFX0lOVCBoaWdoOwoJCSAgaW50IG92ZXJmbG93ID0gbmVnX2RvdWJsZSAoVFJFRV9JTlRfQ1NUX0xPVyAoYXJnMCksCgkJCQkJICAgICBUUkVFX0lOVF9DU1RfSElHSCAoYXJnMCksCgkJCQkJICAgICAmbG93LCAmaGlnaCk7CgkJICB0ID0gYnVpbGRfaW50XzIgKGxvdywgaGlnaCk7CgkJICBUUkVFX1RZUEUgKHQpID0gdHlwZTsKCQkgIFRSRUVfT1ZFUkZMT1cgKHQpCgkJICAgID0gKFRSRUVfT1ZFUkZMT1cgKGFyZzApCgkJICAgICAgIHwgZm9yY2VfZml0X3R5cGUgKHQsIG92ZXJmbG93KSk7CgkJICBUUkVFX0NPTlNUQU5UX09WRVJGTE9XICh0KQoJCSAgICA9IFRSRUVfT1ZFUkZMT1cgKHQpIHwgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAoYXJnMCk7CgkJfQoJICAgIH0KCSAgZWxzZSBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBSRUFMX0NTVCkKCSAgICB7CgkgICAgICBpZiAoUkVBTF9WQUxVRV9ORUdBVElWRSAoVFJFRV9SRUFMX0NTVCAoYXJnMCkpKQoJCXQgPSBidWlsZF9yZWFsICh0eXBlLAoJCQkJUkVBTF9WQUxVRV9ORUdBVEUgKFRSRUVfUkVBTF9DU1QgKGFyZzApKSk7CgkgICAgfQoJfQogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKGFyZzApID09IE5FR0FURV9FWFBSKQoJcmV0dXJuIGZvbGQgKGJ1aWxkMSAoQUJTX0VYUFIsIHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnMCwgMCkpKTsKICAgICAgLyogQ29udmVydCBmYWJzKChkb3VibGUpZmxvYXQpIGludG8gKGRvdWJsZSlmYWJzZihmbG9hdCkuICAqLwogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKGFyZzApID09IE5PUF9FWFBSCgkgICAgICAgJiYgVFJFRV9DT0RFICh0eXBlKSA9PSBSRUFMX1RZUEUpCgl7CgkgIHRyZWUgdGFyZzAgPSBzdHJpcF9mbG9hdF9leHRlbnNpb25zIChhcmcwKTsKCSAgaWYgKHRhcmcwICE9IGFyZzApCgkgICAgcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgZm9sZCAoYnVpbGQxIChBQlNfRVhQUiwKCQkJCQkJICAgICBUUkVFX1RZUEUgKHRhcmcwKSwKCQkJCQkJICAgICB0YXJnMCkpKTsKCX0KICAgICAgZWxzZSBpZiAodHJlZV9leHByX25vbm5lZ2F0aXZlX3AgKGFyZzApKQoJcmV0dXJuIGFyZzA7CiAgICAgIHJldHVybiB0OwoKICAgIGNhc2UgQ09OSl9FWFBSOgogICAgICBpZiAoVFJFRV9DT0RFIChUUkVFX1RZUEUgKGFyZzApKSAhPSBDT01QTEVYX1RZUEUpCglyZXR1cm4gZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcwKTsKICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBDT01QTEVYX0VYUFIpCglyZXR1cm4gYnVpbGQgKENPTVBMRVhfRVhQUiwgdHlwZSwKCQkgICAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCSAgICAgIG5lZ2F0ZV9leHByIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSk7CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQ09NUExFWF9DU1QpCglyZXR1cm4gYnVpbGRfY29tcGxleCAodHlwZSwgVFJFRV9SRUFMUEFSVCAoYXJnMCksCgkJCSAgICAgIG5lZ2F0ZV9leHByIChUUkVFX0lNQUdQQVJUIChhcmcwKSkpOwogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKGFyZzApID09IFBMVVNfRVhQUiB8fCBUUkVFX0NPREUgKGFyZzApID09IE1JTlVTX0VYUFIpCglyZXR1cm4gZm9sZCAoYnVpbGQgKFRSRUVfQ09ERSAoYXJnMCksIHR5cGUsCgkJCSAgICBmb2xkIChidWlsZDEgKENPTkpfRVhQUiwgdHlwZSwKCQkJCQkgIFRSRUVfT1BFUkFORCAoYXJnMCwgMCkpKSwKCQkJICAgIGZvbGQgKGJ1aWxkMSAoQ09OSl9FWFBSLAoJCQkJCSAgdHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkpKSk7CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQ09OSl9FWFBSKQoJcmV0dXJuIFRSRUVfT1BFUkFORCAoYXJnMCwgMCk7CiAgICAgIHJldHVybiB0OwoKICAgIGNhc2UgQklUX05PVF9FWFBSOgogICAgICBpZiAod2lucykKCXsKCSAgdCA9IGJ1aWxkX2ludF8yICh+IFRSRUVfSU5UX0NTVF9MT1cgKGFyZzApLAoJCQkgICB+IFRSRUVfSU5UX0NTVF9ISUdIIChhcmcwKSk7CgkgIFRSRUVfVFlQRSAodCkgPSB0eXBlOwoJICBmb3JjZV9maXRfdHlwZSAodCwgMCk7CgkgIFRSRUVfT1ZFUkZMT1cgKHQpID0gVFJFRV9PVkVSRkxPVyAoYXJnMCk7CgkgIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKHQpID0gVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAoYXJnMCk7Cgl9CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQklUX05PVF9FWFBSKQoJcmV0dXJuIFRSRUVfT1BFUkFORCAoYXJnMCwgMCk7CiAgICAgIHJldHVybiB0OwoKICAgIGNhc2UgUExVU19FWFBSOgogICAgICAvKiBBICsgKC1CKSAtPiBBIC0gQiAqLwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBORUdBVEVfRVhQUikKCXJldHVybiBmb2xkIChidWlsZCAoTUlOVVNfRVhQUiwgdHlwZSwgYXJnMCwgVFJFRV9PUEVSQU5EIChhcmcxLCAwKSkpOwogICAgICAvKiAoLUEpICsgQiAtPiBCIC0gQSAqLwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBORUdBVEVfRVhQUikKCXJldHVybiBmb2xkIChidWlsZCAoTUlOVVNfRVhQUiwgdHlwZSwgYXJnMSwgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSkpOwogICAgICBlbHNlIGlmICghIEZMT0FUX1RZUEVfUCAodHlwZSkpCgl7CgkgIGlmIChpbnRlZ2VyX3plcm9wIChhcmcxKSkKCSAgICByZXR1cm4gbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcwKSk7CgoJICAvKiBJZiB3ZSBhcmUgYWRkaW5nIHR3byBCSVRfQU5EX0VYUFIncywgYm90aCBvZiB3aGljaCBhcmUgYW5kJ2luZwoJICAgICB3aXRoIGEgY29uc3RhbnQsIGFuZCB0aGUgdHdvIGNvbnN0YW50cyBoYXZlIG5vIGJpdHMgaW4gY29tbW9uLAoJICAgICB3ZSBzaG91bGQgdHJlYXQgdGhpcyBhcyBhIEJJVF9JT1JfRVhQUiBzaW5jZSB0aGlzIG1heSBwcm9kdWNlIG1vcmUKCSAgICAgc2ltcGxpZmljYXRpb25zLiAgKi8KCSAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQklUX0FORF9FWFBSCgkgICAgICAmJiBUUkVFX0NPREUgKGFyZzEpID09IEJJVF9BTkRfRVhQUgoJICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSA9PSBJTlRFR0VSX0NTVAoJICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzEsIDEpKSA9PSBJTlRFR0VSX0NTVAoJICAgICAgJiYgaW50ZWdlcl96ZXJvcCAoY29uc3RfYmlub3AgKEJJVF9BTkRfRVhQUiwKCQkJCQkgICAgIFRSRUVfT1BFUkFORCAoYXJnMCwgMSksCgkJCQkJICAgICBUUkVFX09QRVJBTkQgKGFyZzEsIDEpLCAwKSkpCgkgICAgewoJICAgICAgY29kZSA9IEJJVF9JT1JfRVhQUjsKCSAgICAgIGdvdG8gYml0X2lvcjsKCSAgICB9CgoJICAvKiBSZWFzc29jaWF0ZSAocGx1cyAocGx1cyAobXVsdCkgKGZvbykpIChtdWx0KSkgYXMKCSAgICAgKHBsdXMgKHBsdXMgKG11bHQpIChtdWx0KSkgKGZvbykpIHNvIHRoYXQgd2UgY2FuCgkgICAgIHRha2UgYWR2YW50YWdlIG9mIHRoZSBmYWN0b3JpbmcgY2FzZXMgYmVsb3cuICAqLwoJICBpZiAoKFRSRUVfQ09ERSAoYXJnMCkgPT0gUExVU19FWFBSCgkgICAgICAgJiYgVFJFRV9DT0RFIChhcmcxKSA9PSBNVUxUX0VYUFIpCgkgICAgICB8fCAoVFJFRV9DT0RFIChhcmcxKSA9PSBQTFVTX0VYUFIKCQkgICYmIFRSRUVfQ09ERSAoYXJnMCkgPT0gTVVMVF9FWFBSKSkKCSAgICB7CgkgICAgICB0cmVlIHBhcmcwLCBwYXJnMSwgcGFyZywgbWFyZzsKCgkgICAgICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBQTFVTX0VYUFIpCgkJcGFyZyA9IGFyZzAsIG1hcmcgPSBhcmcxOwoJICAgICAgZWxzZQoJCXBhcmcgPSBhcmcxLCBtYXJnID0gYXJnMDsKCSAgICAgIHBhcmcwID0gVFJFRV9PUEVSQU5EIChwYXJnLCAwKTsKCSAgICAgIHBhcmcxID0gVFJFRV9PUEVSQU5EIChwYXJnLCAxKTsKCSAgICAgIFNUUklQX05PUFMgKHBhcmcwKTsKCSAgICAgIFNUUklQX05PUFMgKHBhcmcxKTsKCgkgICAgICBpZiAoVFJFRV9DT0RFIChwYXJnMCkgPT0gTVVMVF9FWFBSCgkJICAmJiBUUkVFX0NPREUgKHBhcmcxKSAhPSBNVUxUX0VYUFIpCgkJcmV0dXJuIGZvbGQgKGJ1aWxkIChQTFVTX0VYUFIsIHR5cGUsCgkJCQkgICAgZm9sZCAoYnVpbGQgKFBMVVNfRVhQUiwgdHlwZSwKCQkJCQkJIGZvbGRfY29udmVydCAodHlwZSwgcGFyZzApLAoJCQkJCQkgZm9sZF9jb252ZXJ0ICh0eXBlLCBtYXJnKSkpLAoJCQkJICAgIGZvbGRfY29udmVydCAodHlwZSwgcGFyZzEpKSk7CgkgICAgICBpZiAoVFJFRV9DT0RFIChwYXJnMCkgIT0gTVVMVF9FWFBSCgkJICAmJiBUUkVFX0NPREUgKHBhcmcxKSA9PSBNVUxUX0VYUFIpCgkJcmV0dXJuIGZvbGQgKGJ1aWxkIChQTFVTX0VYUFIsIHR5cGUsCgkJCQkgICAgZm9sZCAoYnVpbGQgKFBMVVNfRVhQUiwgdHlwZSwKCQkJCQkJIGZvbGRfY29udmVydCAodHlwZSwgcGFyZzEpLAoJCQkJCQkgZm9sZF9jb252ZXJ0ICh0eXBlLCBtYXJnKSkpLAoJCQkJICAgIGZvbGRfY29udmVydCAodHlwZSwgcGFyZzApKSk7CgkgICAgfQoKCSAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gTVVMVF9FWFBSICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gTVVMVF9FWFBSKQoJICAgIHsKCSAgICAgIHRyZWUgYXJnMDAsIGFyZzAxLCBhcmcxMCwgYXJnMTE7CgkgICAgICB0cmVlIGFsdDAgPSBOVUxMX1RSRUUsIGFsdDEgPSBOVUxMX1RSRUUsIHNhbWU7CgoJICAgICAgLyogKEEgKiBDKSArIChCICogQykgLT4gKEErQikgKiBDLgoJCSBXZSBhcmUgbW9zdCBjb25jZXJuZWQgYWJvdXQgdGhlIGNhc2Ugd2hlcmUgQyBpcyBhIGNvbnN0YW50LAoJCSBidXQgb3RoZXIgY29tYmluYXRpb25zIHNob3cgdXAgZHVyaW5nIGxvb3AgcmVkdWN0aW9uLiAgU2luY2UKCQkgaXQgaXMgbm90IGRpZmZpY3VsdCwgdHJ5IGFsbCBmb3VyIHBvc3NpYmlsaXRpZXMuICAqLwoKCSAgICAgIGFyZzAwID0gVFJFRV9PUEVSQU5EIChhcmcwLCAwKTsKCSAgICAgIGFyZzAxID0gVFJFRV9PUEVSQU5EIChhcmcwLCAxKTsKCSAgICAgIGFyZzEwID0gVFJFRV9PUEVSQU5EIChhcmcxLCAwKTsKCSAgICAgIGFyZzExID0gVFJFRV9PUEVSQU5EIChhcmcxLCAxKTsKCSAgICAgIHNhbWUgPSBOVUxMX1RSRUU7CgoJICAgICAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoYXJnMDEsIGFyZzExLCAwKSkKCQlzYW1lID0gYXJnMDEsIGFsdDAgPSBhcmcwMCwgYWx0MSA9IGFyZzEwOwoJICAgICAgZWxzZSBpZiAob3BlcmFuZF9lcXVhbF9wIChhcmcwMCwgYXJnMTAsIDApKQoJCXNhbWUgPSBhcmcwMCwgYWx0MCA9IGFyZzAxLCBhbHQxID0gYXJnMTE7CgkgICAgICBlbHNlIGlmIChvcGVyYW5kX2VxdWFsX3AgKGFyZzAwLCBhcmcxMSwgMCkpCgkJc2FtZSA9IGFyZzAwLCBhbHQwID0gYXJnMDEsIGFsdDEgPSBhcmcxMDsKCSAgICAgIGVsc2UgaWYgKG9wZXJhbmRfZXF1YWxfcCAoYXJnMDEsIGFyZzEwLCAwKSkKCQlzYW1lID0gYXJnMDEsIGFsdDAgPSBhcmcwMCwgYWx0MSA9IGFyZzExOwoKCSAgICAgIC8qIE5vIGlkZW50aWNhbCBtdWx0aXBsaWNhbmRzOyBzZWUgaWYgd2UgY2FuIGZpbmQgYSBjb21tb24KCQkgcG93ZXItb2YtdHdvIGZhY3RvciBpbiBub24tcG93ZXItb2YtdHdvIG11bHRpcGxpZXMuICBUaGlzCgkJIGNhbiBoZWxwIGluIG11bHRpLWRpbWVuc2lvbmFsIGFycmF5IGFjY2Vzcy4gICovCgkgICAgICBlbHNlIGlmIChUUkVFX0NPREUgKGFyZzAxKSA9PSBJTlRFR0VSX0NTVAoJCSAgICAgICAmJiBUUkVFX0NPREUgKGFyZzExKSA9PSBJTlRFR0VSX0NTVAoJCSAgICAgICAmJiBUUkVFX0lOVF9DU1RfSElHSCAoYXJnMDEpID09IDAKCQkgICAgICAgJiYgVFJFRV9JTlRfQ1NUX0hJR0ggKGFyZzExKSA9PSAwKQoJCXsKCQkgIEhPU1RfV0lERV9JTlQgaW50MDEsIGludDExLCB0bXA7CgkJICBpbnQwMSA9IFRSRUVfSU5UX0NTVF9MT1cgKGFyZzAxKTsKCQkgIGludDExID0gVFJFRV9JTlRfQ1NUX0xPVyAoYXJnMTEpOwoKCQkgIC8qIE1vdmUgbWluIG9mIGFic29sdXRlIHZhbHVlcyB0byBpbnQxMS4gICovCgkJICBpZiAoKGludDAxID49IDAgPyBpbnQwMSA6IC1pbnQwMSkKCQkgICAgICA8IChpbnQxMSA+PSAwID8gaW50MTEgOiAtaW50MTEpKQoJCSAgICB7CgkJICAgICAgdG1wID0gaW50MDEsIGludDAxID0gaW50MTEsIGludDExID0gdG1wOwoJCSAgICAgIGFsdDAgPSBhcmcwMCwgYXJnMDAgPSBhcmcxMCwgYXJnMTAgPSBhbHQwOwoJCSAgICAgIGFsdDAgPSBhcmcwMSwgYXJnMDEgPSBhcmcxMSwgYXJnMTEgPSBhbHQwOwoJCSAgICB9CgoJCSAgaWYgKGV4YWN0X2xvZzIgKGludDExKSA+IDAgJiYgaW50MDEgJSBpbnQxMSA9PSAwKQoJCSAgICB7CgkJICAgICAgYWx0MCA9IGZvbGQgKGJ1aWxkIChNVUxUX0VYUFIsIHR5cGUsIGFyZzAwLAoJCQkJCSAgYnVpbGRfaW50XzIgKGludDAxIC8gaW50MTEsIDApKSk7CgkJICAgICAgYWx0MSA9IGFyZzEwOwoJCSAgICAgIHNhbWUgPSBhcmcxMTsKCQkgICAgfQoJCX0KCgkgICAgICBpZiAoc2FtZSkKCQlyZXR1cm4gZm9sZCAoYnVpbGQgKE1VTFRfRVhQUiwgdHlwZSwKCQkJCSAgICBmb2xkIChidWlsZCAoUExVU19FWFBSLCB0eXBlLCBhbHQwLCBhbHQxKSksCgkJCQkgICAgc2FtZSkpOwoJICAgIH0KCX0KICAgICAgZWxzZQoJewoJICAvKiBTZWUgaWYgQVJHMSBpcyB6ZXJvIGFuZCBYICsgQVJHMSByZWR1Y2VzIHRvIFguICAqLwoJICBpZiAoZm9sZF9yZWFsX3plcm9fYWRkaXRpb25fcCAoVFJFRV9UWVBFIChhcmcwKSwgYXJnMSwgMCkpCgkgICAgcmV0dXJuIG5vbl9sdmFsdWUgKGZvbGRfY29udmVydCAodHlwZSwgYXJnMCkpOwoKCSAgLyogTGlrZXdpc2UgaWYgdGhlIG9wZXJhbmRzIGFyZSByZXZlcnNlZC4gICovCgkgIGlmIChmb2xkX3JlYWxfemVyb19hZGRpdGlvbl9wIChUUkVFX1RZUEUgKGFyZzEpLCBhcmcwLCAwKSkKCSAgICByZXR1cm4gbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcxKSk7CgoJICAvKiBDb252ZXJ0IHgreCBpbnRvIHgqMi4wLiAgKi8KCSAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoYXJnMCwgYXJnMSwgMCkKCSAgICAgICYmIFNDQUxBUl9GTE9BVF9UWVBFX1AgKHR5cGUpKQoJICAgIHJldHVybiBmb2xkIChidWlsZCAoTVVMVF9FWFBSLCB0eXBlLCBhcmcwLAoJCQkJYnVpbGRfcmVhbCAodHlwZSwgZGNvbnN0MikpKTsKCgkgIC8qIENvbnZlcnQgeCpjK3ggaW50byB4KihjKzEpLiAgKi8KCSAgaWYgKGZsYWdfdW5zYWZlX21hdGhfb3B0aW1pemF0aW9ucwoJICAgICAgJiYgVFJFRV9DT0RFIChhcmcwKSA9PSBNVUxUX0VYUFIKCSAgICAgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkgPT0gUkVBTF9DU1QKCSAgICAgICYmICEgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkKCSAgICAgICYmIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgYXJnMSwgMCkpCgkgICAgewoJICAgICAgUkVBTF9WQUxVRV9UWVBFIGM7CgoJICAgICAgYyA9IFRSRUVfUkVBTF9DU1QgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpOwoJICAgICAgcmVhbF9hcml0aG1ldGljICgmYywgUExVU19FWFBSLCAmYywgJmRjb25zdDEpOwoJICAgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChNVUxUX0VYUFIsIHR5cGUsIGFyZzEsCgkJCQkgIGJ1aWxkX3JlYWwgKHR5cGUsIGMpKSk7CgkgICAgfQoKCSAgLyogQ29udmVydCB4K3gqYyBpbnRvIHgqKGMrMSkuICAqLwoJICBpZiAoZmxhZ191bnNhZmVfbWF0aF9vcHRpbWl6YXRpb25zCgkgICAgICAmJiBUUkVFX0NPREUgKGFyZzEpID09IE1VTFRfRVhQUgoJICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzEsIDEpKSA9PSBSRUFMX0NTVAoJICAgICAgJiYgISBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChUUkVFX09QRVJBTkQgKGFyZzEsIDEpKQoJICAgICAgJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzEsIDApLCBhcmcwLCAwKSkKCSAgICB7CgkgICAgICBSRUFMX1ZBTFVFX1RZUEUgYzsKCgkgICAgICBjID0gVFJFRV9SRUFMX0NTVCAoVFJFRV9PUEVSQU5EIChhcmcxLCAxKSk7CgkgICAgICByZWFsX2FyaXRobWV0aWMgKCZjLCBQTFVTX0VYUFIsICZjLCAmZGNvbnN0MSk7CgkgICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKE1VTFRfRVhQUiwgdHlwZSwgYXJnMCwKCQkJCSAgYnVpbGRfcmVhbCAodHlwZSwgYykpKTsKCSAgICB9CgoJICAvKiBDb252ZXJ0IHgqYzEreCpjMiBpbnRvIHgqKGMxK2MyKS4gICovCgkgIGlmIChmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMKCSAgICAgICYmIFRSRUVfQ09ERSAoYXJnMCkgPT0gTVVMVF9FWFBSCgkgICAgICAmJiBUUkVFX0NPREUgKGFyZzEpID09IE1VTFRfRVhQUgoJICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSA9PSBSRUFMX0NTVAoJICAgICAgJiYgISBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKQoJICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzEsIDEpKSA9PSBSRUFMX0NTVAoJICAgICAgJiYgISBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChUUkVFX09QRVJBTkQgKGFyZzEsIDEpKQoJICAgICAgJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkJICBUUkVFX09QRVJBTkQgKGFyZzEsIDApLCAwKSkKCSAgICB7CgkgICAgICBSRUFMX1ZBTFVFX1RZUEUgYzEsIGMyOwoKCSAgICAgIGMxID0gVFJFRV9SRUFMX0NTVCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSk7CgkgICAgICBjMiA9IFRSRUVfUkVBTF9DU1QgKFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpOwoJICAgICAgcmVhbF9hcml0aG1ldGljICgmYzEsIFBMVVNfRVhQUiwgJmMxLCAmYzIpOwoJICAgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChNVUxUX0VYUFIsIHR5cGUsCgkJCQkgIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksCgkJCQkgIGJ1aWxkX3JlYWwgKHR5cGUsIGMxKSkpOwoJICAgIH0KCX0KCiAgICAgYml0X3JvdGF0ZToKICAgICAgLyogKEEgPDwgQzEpICsgKEEgPj4gQzIpIGlmIEEgaXMgdW5zaWduZWQgYW5kIEMxK0MyIGlzIHRoZSBzaXplIG9mIEEKCSBpcyBhIHJvdGF0ZSBvZiBBIGJ5IEMxIGJpdHMuICAqLwogICAgICAvKiAoQSA8PCBCKSArIChBID4+IChaIC0gQikpIGlmIEEgaXMgdW5zaWduZWQgYW5kIFogaXMgdGhlIHNpemUgb2YgQQoJIGlzIGEgcm90YXRlIG9mIEEgYnkgQiBiaXRzLiAgKi8KICAgICAgewoJZW51bSB0cmVlX2NvZGUgY29kZTAsIGNvZGUxOwoJY29kZTAgPSBUUkVFX0NPREUgKGFyZzApOwoJY29kZTEgPSBUUkVFX0NPREUgKGFyZzEpOwoJaWYgKCgoY29kZTAgPT0gUlNISUZUX0VYUFIgJiYgY29kZTEgPT0gTFNISUZUX0VYUFIpCgkgICAgIHx8IChjb2RlMSA9PSBSU0hJRlRfRVhQUiAmJiBjb2RlMCA9PSBMU0hJRlRfRVhQUikpCgkgICAgJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkgICAgICAgIFRSRUVfT1BFUkFORCAoYXJnMSwgMCksIDApCgkgICAgJiYgVFJFRV9VTlNJR05FRCAoVFJFRV9UWVBFIChUUkVFX09QRVJBTkQgKGFyZzAsIDApKSkpCgkgIHsKCSAgICB0cmVlIHRyZWUwMSwgdHJlZTExOwoJICAgIGVudW0gdHJlZV9jb2RlIGNvZGUwMSwgY29kZTExOwoKCSAgICB0cmVlMDEgPSBUUkVFX09QRVJBTkQgKGFyZzAsIDEpOwoJICAgIHRyZWUxMSA9IFRSRUVfT1BFUkFORCAoYXJnMSwgMSk7CgkgICAgU1RSSVBfTk9QUyAodHJlZTAxKTsKCSAgICBTVFJJUF9OT1BTICh0cmVlMTEpOwoJICAgIGNvZGUwMSA9IFRSRUVfQ09ERSAodHJlZTAxKTsKCSAgICBjb2RlMTEgPSBUUkVFX0NPREUgKHRyZWUxMSk7CgkgICAgaWYgKGNvZGUwMSA9PSBJTlRFR0VSX0NTVAoJCSYmIGNvZGUxMSA9PSBJTlRFR0VSX0NTVAoJCSYmIFRSRUVfSU5UX0NTVF9ISUdIICh0cmVlMDEpID09IDAKCQkmJiBUUkVFX0lOVF9DU1RfSElHSCAodHJlZTExKSA9PSAwCgkJJiYgKChUUkVFX0lOVF9DU1RfTE9XICh0cmVlMDEpICsgVFJFRV9JTlRfQ1NUX0xPVyAodHJlZTExKSkKCQkgICAgPT0gVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSkpKSkKCSAgICAgIHJldHVybiBidWlsZCAoTFJPVEFURV9FWFBSLCB0eXBlLCBUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkgICAgY29kZTAgPT0gTFNISUZUX0VYUFIgPyB0cmVlMDEgOiB0cmVlMTEpOwoJICAgIGVsc2UgaWYgKGNvZGUxMSA9PSBNSU5VU19FWFBSKQoJICAgICAgewoJCXRyZWUgdHJlZTExMCwgdHJlZTExMTsKCQl0cmVlMTEwID0gVFJFRV9PUEVSQU5EICh0cmVlMTEsIDApOwoJCXRyZWUxMTEgPSBUUkVFX09QRVJBTkQgKHRyZWUxMSwgMSk7CgkJU1RSSVBfTk9QUyAodHJlZTExMCk7CgkJU1RSSVBfTk9QUyAodHJlZTExMSk7CgkJaWYgKFRSRUVfQ09ERSAodHJlZTExMCkgPT0gSU5URUdFUl9DU1QKCQkgICAgJiYgMCA9PSBjb21wYXJlX3RyZWVfaW50ICh0cmVlMTEwLAoJCQkJCSAgICAgIFRZUEVfUFJFQ0lTSU9OCgkJCQkJICAgICAgKFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5ECgkJCQkJCQkgIChhcmcwLCAwKSkpKQoJCSAgICAmJiBvcGVyYW5kX2VxdWFsX3AgKHRyZWUwMSwgdHJlZTExMSwgMCkpCgkJICByZXR1cm4gYnVpbGQgKChjb2RlMCA9PSBMU0hJRlRfRVhQUgoJCQkJID8gTFJPVEFURV9FWFBSCgkJCQkgOiBSUk9UQVRFX0VYUFIpLAoJCQkJdHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgdHJlZTAxKTsKCSAgICAgIH0KCSAgICBlbHNlIGlmIChjb2RlMDEgPT0gTUlOVVNfRVhQUikKCSAgICAgIHsKCQl0cmVlIHRyZWUwMTAsIHRyZWUwMTE7CgkJdHJlZTAxMCA9IFRSRUVfT1BFUkFORCAodHJlZTAxLCAwKTsKCQl0cmVlMDExID0gVFJFRV9PUEVSQU5EICh0cmVlMDEsIDEpOwoJCVNUUklQX05PUFMgKHRyZWUwMTApOwoJCVNUUklQX05PUFMgKHRyZWUwMTEpOwoJCWlmIChUUkVFX0NPREUgKHRyZWUwMTApID09IElOVEVHRVJfQ1NUCgkJICAgICYmIDAgPT0gY29tcGFyZV90cmVlX2ludCAodHJlZTAxMCwKCQkJCQkgICAgICBUWVBFX1BSRUNJU0lPTgoJCQkJCSAgICAgIChUUkVFX1RZUEUgKFRSRUVfT1BFUkFORAoJCQkJCQkJICAoYXJnMCwgMCkpKSkKCQkgICAgJiYgb3BlcmFuZF9lcXVhbF9wICh0cmVlMTEsIHRyZWUwMTEsIDApKQoJCSAgcmV0dXJuIGJ1aWxkICgoY29kZTAgIT0gTFNISUZUX0VYUFIKCQkJCSA/IExST1RBVEVfRVhQUgoJCQkJIDogUlJPVEFURV9FWFBSKSwKCQkJCXR5cGUsIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksIHRyZWUxMSk7CgkgICAgICB9CgkgIH0KICAgICAgfQoKICAgIGFzc29jaWF0ZToKICAgICAgLyogSW4gbW9zdCBsYW5ndWFnZXMsIGNhbid0IGFzc29jaWF0ZSBvcGVyYXRpb25zIG9uIGZsb2F0cyB0aHJvdWdoCgkgcGFyZW50aGVzZXMuICBSYXRoZXIgdGhhbiByZW1lbWJlciB3aGVyZSB0aGUgcGFyZW50aGVzZXMgd2VyZSwgd2UKCSBkb24ndCBhc3NvY2lhdGUgZmxvYXRzIGF0IGFsbCwgdW5sZXNzIHRoZSB1c2VyIGhhcyBzcGVjaWZpZWQKCSAtZnVuc2FmZS1tYXRoLW9wdGltaXphdGlvbnMuICAqLwoKICAgICAgaWYgKCEgd2lucwoJICAmJiAoISBGTE9BVF9UWVBFX1AgKHR5cGUpIHx8IGZsYWdfdW5zYWZlX21hdGhfb3B0aW1pemF0aW9ucykpCgl7CgkgIHRyZWUgdmFyMCwgY29uMCwgbGl0MCwgbWludXNfbGl0MDsKCSAgdHJlZSB2YXIxLCBjb24xLCBsaXQxLCBtaW51c19saXQxOwoKCSAgLyogU3BsaXQgYm90aCB0cmVlcyBpbnRvIHZhcmlhYmxlcywgY29uc3RhbnRzLCBhbmQgbGl0ZXJhbHMuICBUaGVuCgkgICAgIGFzc29jaWF0ZSBlYWNoIGdyb3VwIHRvZ2V0aGVyLCB0aGUgY29uc3RhbnRzIHdpdGggbGl0ZXJhbHMsCgkgICAgIHRoZW4gdGhlIHJlc3VsdCB3aXRoIHZhcmlhYmxlcy4gIFRoaXMgaW5jcmVhc2VzIHRoZSBjaGFuY2VzIG9mCgkgICAgIGxpdGVyYWxzIGJlaW5nIHJlY29tYmluZWQgbGF0ZXIgYW5kIG9mIGdlbmVyYXRpbmcgcmVsb2NhdGFibGUKCSAgICAgZXhwcmVzc2lvbnMgZm9yIHRoZSBzdW0gb2YgYSBjb25zdGFudCBhbmQgbGl0ZXJhbC4gICovCgkgIHZhcjAgPSBzcGxpdF90cmVlIChhcmcwLCBjb2RlLCAmY29uMCwgJmxpdDAsICZtaW51c19saXQwLCAwKTsKCSAgdmFyMSA9IHNwbGl0X3RyZWUgKGFyZzEsIGNvZGUsICZjb24xLCAmbGl0MSwgJm1pbnVzX2xpdDEsCgkJCSAgICAgY29kZSA9PSBNSU5VU19FWFBSKTsKCgkgIC8qIE9ubHkgZG8gc29tZXRoaW5nIGlmIHdlIGZvdW5kIG1vcmUgdGhhbiB0d28gb2JqZWN0cy4gIE90aGVyd2lzZSwKCSAgICAgbm90aGluZyBoYXMgY2hhbmdlZCBhbmQgd2UgcmlzayBpbmZpbml0ZSByZWN1cnNpb24uICAqLwoJICBpZiAoMiA8ICgodmFyMCAhPSAwKSArICh2YXIxICE9IDApCgkJICAgKyAoY29uMCAhPSAwKSArIChjb24xICE9IDApCgkJICAgKyAobGl0MCAhPSAwKSArIChsaXQxICE9IDApCgkJICAgKyAobWludXNfbGl0MCAhPSAwKSArIChtaW51c19saXQxICE9IDApKSkKCSAgICB7CgkgICAgICAvKiBSZWNvbWJpbmUgTUlOVVNfRVhQUiBvcGVyYW5kcyBieSB1c2luZyBQTFVTX0VYUFIuICAqLwoJICAgICAgaWYgKGNvZGUgPT0gTUlOVVNfRVhQUikKCQljb2RlID0gUExVU19FWFBSOwoKCSAgICAgIHZhcjAgPSBhc3NvY2lhdGVfdHJlZXMgKHZhcjAsIHZhcjEsIGNvZGUsIHR5cGUpOwoJICAgICAgY29uMCA9IGFzc29jaWF0ZV90cmVlcyAoY29uMCwgY29uMSwgY29kZSwgdHlwZSk7CgkgICAgICBsaXQwID0gYXNzb2NpYXRlX3RyZWVzIChsaXQwLCBsaXQxLCBjb2RlLCB0eXBlKTsKCSAgICAgIG1pbnVzX2xpdDAgPSBhc3NvY2lhdGVfdHJlZXMgKG1pbnVzX2xpdDAsIG1pbnVzX2xpdDEsIGNvZGUsIHR5cGUpOwoKCSAgICAgIC8qIFByZXNlcnZlIHRoZSBNSU5VU19FWFBSIGlmIHRoZSBuZWdhdGl2ZSBwYXJ0IG9mIHRoZSBsaXRlcmFsIGlzCgkJIGdyZWF0ZXIgdGhhbiB0aGUgcG9zaXRpdmUgcGFydC4gIE90aGVyd2lzZSwgdGhlIG11bHRpcGxpY2F0aXZlCgkJIGZvbGRpbmcgY29kZSAoaS5lIGV4dHJhY3RfbXVsZGl2KSBtYXkgYmUgZm9vbGVkIGluIGNhc2UKCQkgdW5zaWduZWQgY29uc3RhbnRzIGFyZSBzdWJ0cmFjdGVkLCBsaWtlIGluIHRoZSBmb2xsb3dpbmcKCQkgZXhhbXBsZTogKChYKjIgKyA0KSAtIDhVKS8yLiAgKi8KCSAgICAgIGlmIChtaW51c19saXQwICYmIGxpdDApCgkJewoJCSAgaWYgKFRSRUVfQ09ERSAobGl0MCkgPT0gSU5URUdFUl9DU1QKCQkgICAgICAmJiBUUkVFX0NPREUgKG1pbnVzX2xpdDApID09IElOVEVHRVJfQ1NUCgkJICAgICAgJiYgdHJlZV9pbnRfY3N0X2x0IChsaXQwLCBtaW51c19saXQwKSkKCQkgICAgewoJCSAgICAgIG1pbnVzX2xpdDAgPSBhc3NvY2lhdGVfdHJlZXMgKG1pbnVzX2xpdDAsIGxpdDAsCgkJCQkJCSAgICBNSU5VU19FWFBSLCB0eXBlKTsKCQkgICAgICBsaXQwID0gMDsKCQkgICAgfQoJCSAgZWxzZQoJCSAgICB7CgkJICAgICAgbGl0MCA9IGFzc29jaWF0ZV90cmVlcyAobGl0MCwgbWludXNfbGl0MCwKCQkJCQkgICAgICBNSU5VU19FWFBSLCB0eXBlKTsKCQkgICAgICBtaW51c19saXQwID0gMDsKCQkgICAgfQoJCX0KCSAgICAgIGlmIChtaW51c19saXQwKQoJCXsKCQkgIGlmIChjb24wID09IDApCgkJICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsCgkJCQkJIGFzc29jaWF0ZV90cmVlcyAodmFyMCwgbWludXNfbGl0MCwKCQkJCQkJCSAgTUlOVVNfRVhQUiwgdHlwZSkpOwoJCSAgZWxzZQoJCSAgICB7CgkJICAgICAgY29uMCA9IGFzc29jaWF0ZV90cmVlcyAoY29uMCwgbWludXNfbGl0MCwKCQkJCQkgICAgICBNSU5VU19FWFBSLCB0eXBlKTsKCQkgICAgICByZXR1cm4gZm9sZF9jb252ZXJ0ICh0eXBlLAoJCQkJCSAgIGFzc29jaWF0ZV90cmVlcyAodmFyMCwgY29uMCwKCQkJCQkJCSAgICBQTFVTX0VYUFIsIHR5cGUpKTsKCQkgICAgfQoJCX0KCgkgICAgICBjb24wID0gYXNzb2NpYXRlX3RyZWVzIChjb24wLCBsaXQwLCBjb2RlLCB0eXBlKTsKCSAgICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIGFzc29jaWF0ZV90cmVlcyAodmFyMCwgY29uMCwKCQkJCQkJCSAgY29kZSwgdHlwZSkpOwoJICAgIH0KCX0KCiAgICBiaW5hcnk6CiAgICAgIGlmICh3aW5zKQoJdDEgPSBjb25zdF9iaW5vcCAoY29kZSwgYXJnMCwgYXJnMSwgMCk7CiAgICAgIGlmICh0MSAhPSBOVUxMX1RSRUUpCgl7CgkgIC8qIFRoZSByZXR1cm4gdmFsdWUgc2hvdWxkIGFsd2F5cyBoYXZlCgkgICAgIHRoZSBzYW1lIHR5cGUgYXMgdGhlIG9yaWdpbmFsIGV4cHJlc3Npb24uICAqLwoJICBpZiAoVFJFRV9UWVBFICh0MSkgIT0gVFJFRV9UWVBFICh0KSkKCSAgICB0MSA9IGZvbGRfY29udmVydCAoVFJFRV9UWVBFICh0KSwgdDEpOwoKCSAgcmV0dXJuIHQxOwoJfQogICAgICByZXR1cm4gdDsKCiAgICBjYXNlIE1JTlVTX0VYUFI6CiAgICAgIC8qIEEgLSAoLUIpIC0+IEEgKyBCICovCiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzEpID09IE5FR0FURV9FWFBSKQoJcmV0dXJuIGZvbGQgKGJ1aWxkIChQTFVTX0VYUFIsIHR5cGUsIGFyZzAsIFRSRUVfT1BFUkFORCAoYXJnMSwgMCkpKTsKICAgICAgLyogKC1BKSAtIEIgLT4gKC1CKSAtIEEgIHdoZXJlIEIgaXMgZWFzaWx5IG5lZ2F0ZWQgYW5kIHdlIGNhbiBzd2FwLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gTkVHQVRFX0VYUFIKCSAgJiYgKEZMT0FUX1RZUEVfUCAodHlwZSkKCSAgICAgIHx8IChJTlRFR1JBTF9UWVBFX1AgKHR5cGUpICYmIGZsYWdfd3JhcHYgJiYgIWZsYWdfdHJhcHYpKQoJICAmJiBuZWdhdGVfZXhwcl9wIChhcmcxKQoJICAmJiByZW9yZGVyX29wZXJhbmRzX3AgKGFyZzAsIGFyZzEpKQoJcmV0dXJuIGZvbGQgKGJ1aWxkIChNSU5VU19FWFBSLCB0eXBlLCBuZWdhdGVfZXhwciAoYXJnMSksCgkJCSAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDApKSk7CgogICAgICBpZiAoISBGTE9BVF9UWVBFX1AgKHR5cGUpKQoJewoJICBpZiAoISB3aW5zICYmIGludGVnZXJfemVyb3AgKGFyZzApKQoJICAgIHJldHVybiBuZWdhdGVfZXhwciAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcxKSk7CgkgIGlmIChpbnRlZ2VyX3plcm9wIChhcmcxKSkKCSAgICByZXR1cm4gbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcwKSk7CgoJICAvKiAoQSAqIEMpIC0gKEIgKiBDKSAtPiAoQS1CKSAqIEMuICBTaW5jZSB3ZSBhcmUgbW9zdCBjb25jZXJuZWQKCSAgICAgYWJvdXQgdGhlIGNhc2Ugd2hlcmUgQyBpcyBhIGNvbnN0YW50LCBqdXN0IHRyeSBvbmUgb2YgdGhlCgkgICAgIGZvdXIgcG9zc2liaWxpdGllcy4gICovCgoJICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBNVUxUX0VYUFIgJiYgVFJFRV9DT0RFIChhcmcxKSA9PSBNVUxUX0VYUFIKCSAgICAgICYmIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwKCQkJCSAgVFJFRV9PUEVSQU5EIChhcmcxLCAxKSwgMCkpCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChNVUxUX0VYUFIsIHR5cGUsCgkJCQlmb2xkIChidWlsZCAoTUlOVVNfRVhQUiwgdHlwZSwKCQkJCQkgICAgIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksCgkJCQkJICAgICBUUkVFX09QRVJBTkQgKGFyZzEsIDApKSksCgkJCQlUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSk7CgoJICAvKiBGb2xkIEEgLSAoQSAmIEIpIGludG8gfkIgJiBBLiAgKi8KCSAgaWYgKCFUUkVFX1NJREVfRUZGRUNUUyAoYXJnMCkKCSAgICAgICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gQklUX0FORF9FWFBSKQoJICAgIHsKCSAgICAgIGlmIChvcGVyYW5kX2VxdWFsX3AgKGFyZzAsIFRSRUVfT1BFUkFORCAoYXJnMSwgMSksIDApKQoJCXJldHVybiBmb2xkIChidWlsZCAoQklUX0FORF9FWFBSLCB0eXBlLAoJCQkJICAgIGZvbGQgKGJ1aWxkMSAoQklUX05PVF9FWFBSLCB0eXBlLAoJCQkJCQkgIFRSRUVfT1BFUkFORCAoYXJnMSwgMCkpKSwKCQkJCSAgICBhcmcwKSk7CgkgICAgICBpZiAob3BlcmFuZF9lcXVhbF9wIChhcmcwLCBUUkVFX09QRVJBTkQgKGFyZzEsIDApLCAwKSkKCQlyZXR1cm4gZm9sZCAoYnVpbGQgKEJJVF9BTkRfRVhQUiwgdHlwZSwKCQkJCSAgICBmb2xkIChidWlsZDEgKEJJVF9OT1RfRVhQUiwgdHlwZSwKCQkJCQkJICBUUkVFX09QRVJBTkQgKGFyZzEsIDEpKSksCgkJCQkgICAgYXJnMCkpOwoJICAgIH0KCgkgIC8qIEZvbGQgKEEgJiB+QikgLSAoQSAmIEIpIGludG8gKEEgXiBCKSAtIEIsIHdoZXJlIEIgaXMKCSAgICAgYW55IHBvd2VyIG9mIDIgbWludXMgMS4gICovCgkgIGlmIChUUkVFX0NPREUgKGFyZzApID09IEJJVF9BTkRfRVhQUgoJICAgICAgJiYgVFJFRV9DT0RFIChhcmcxKSA9PSBCSVRfQU5EX0VYUFIKCSAgICAgICYmIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwKCQkJCSAgVFJFRV9PUEVSQU5EIChhcmcxLCAwKSwgMCkpCgkgICAgewoJICAgICAgdHJlZSBtYXNrMCA9IFRSRUVfT1BFUkFORCAoYXJnMCwgMSk7CgkgICAgICB0cmVlIG1hc2sxID0gVFJFRV9PUEVSQU5EIChhcmcxLCAxKTsKCSAgICAgIHRyZWUgdGVtID0gZm9sZCAoYnVpbGQxIChCSVRfTk9UX0VYUFIsIHR5cGUsIG1hc2swKSk7CgkgICAgICAKCSAgICAgIGlmIChvcGVyYW5kX2VxdWFsX3AgKHRlbSwgbWFzazEsIDApKQoJCXsKCQkgIHRlbSA9IGZvbGQgKGJ1aWxkIChCSVRfWE9SX0VYUFIsIHR5cGUsCgkJCQkgICAgIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksIG1hc2sxKSk7CgkJICByZXR1cm4gZm9sZCAoYnVpbGQgKE1JTlVTX0VYUFIsIHR5cGUsIHRlbSwgbWFzazEpKTsKCQl9CgkgICAgfQoJfQoKICAgICAgLyogU2VlIGlmIEFSRzEgaXMgemVybyBhbmQgWCAtIEFSRzEgcmVkdWNlcyB0byBYLiAgKi8KICAgICAgZWxzZSBpZiAoZm9sZF9yZWFsX3plcm9fYWRkaXRpb25fcCAoVFJFRV9UWVBFIChhcmcwKSwgYXJnMSwgMSkpCglyZXR1cm4gbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcwKSk7CgogICAgICAvKiAoQVJHMCAtIEFSRzEpIGlzIHRoZSBzYW1lIGFzICgtQVJHMSArIEFSRzApLiAgU28gY2hlY2sgd2hldGhlcgoJIEFSRzAgaXMgemVybyBhbmQgWCArIEFSRzAgcmVkdWNlcyB0byBYLCBzaW5jZSB0aGF0IHdvdWxkIG1lYW4KCSAoLUFSRzEgKyBBUkcwKSByZWR1Y2VzIHRvIC1BUkcxLiAgKi8KICAgICAgZWxzZSBpZiAoIXdpbnMgJiYgZm9sZF9yZWFsX3plcm9fYWRkaXRpb25fcCAoVFJFRV9UWVBFIChhcmcxKSwgYXJnMCwgMCkpCglyZXR1cm4gbmVnYXRlX2V4cHIgKGZvbGRfY29udmVydCAodHlwZSwgYXJnMSkpOwoKICAgICAgLyogRm9sZCAmeCAtICZ4LiAgVGhpcyBjYW4gaGFwcGVuIGZyb20gJnguZm9vIC0gJnguCgkgVGhpcyBpcyB1bnNhZmUgZm9yIGNlcnRhaW4gZmxvYXRzIGV2ZW4gaW4gbm9uLUlFRUUgZm9ybWF0cy4KCSBJbiBJRUVFLCBpdCBpcyB1bnNhZmUgYmVjYXVzZSBpdCBkb2VzIHdyb25nIGZvciBOYU5zLgoJIEFsc28gbm90ZSB0aGF0IG9wZXJhbmRfZXF1YWxfcCBpcyBhbHdheXMgZmFsc2UgaWYgYW4gb3BlcmFuZAoJIGlzIHZvbGF0aWxlLiAgKi8KCiAgICAgIGlmICgoISBGTE9BVF9UWVBFX1AgKHR5cGUpIHx8IGZsYWdfdW5zYWZlX21hdGhfb3B0aW1pemF0aW9ucykKCSAgJiYgb3BlcmFuZF9lcXVhbF9wIChhcmcwLCBhcmcxLCAwKSkKCXJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfemVyb19ub2RlKTsKCiAgICAgIGdvdG8gYXNzb2NpYXRlOwoKICAgIGNhc2UgTVVMVF9FWFBSOgogICAgICAvKiAoLUEpICogKC1CKSAtPiBBICogQiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gTkVHQVRFX0VYUFIgJiYgbmVnYXRlX2V4cHJfcCAoYXJnMSkpCglyZXR1cm4gZm9sZCAoYnVpbGQgKE1VTFRfRVhQUiwgdHlwZSwKCQkJICAgIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksCgkJCSAgICBuZWdhdGVfZXhwciAoYXJnMSkpKTsKICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gTkVHQVRFX0VYUFIgJiYgbmVnYXRlX2V4cHJfcCAoYXJnMCkpCglyZXR1cm4gZm9sZCAoYnVpbGQgKE1VTFRfRVhQUiwgdHlwZSwKCQkJICAgIG5lZ2F0ZV9leHByIChhcmcwKSwKCQkJICAgIFRSRUVfT1BFUkFORCAoYXJnMSwgMCkpKTsKCiAgICAgIGlmICghIEZMT0FUX1RZUEVfUCAodHlwZSkpCgl7CgkgIGlmIChpbnRlZ2VyX3plcm9wIChhcmcxKSkKCSAgICByZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgYXJnMSwgYXJnMCk7CgkgIGlmIChpbnRlZ2VyX29uZXAgKGFyZzEpKQoJICAgIHJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzApKTsKCgkgIC8qIChhICogKDEgPDwgYikpIGlzIChhIDw8IGIpICAqLwoJICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBMU0hJRlRfRVhQUgoJICAgICAgJiYgaW50ZWdlcl9vbmVwIChUUkVFX09QRVJBTkQgKGFyZzEsIDApKSkKCSAgICByZXR1cm4gZm9sZCAoYnVpbGQgKExTSElGVF9FWFBSLCB0eXBlLCBhcmcwLAoJCQkJVFJFRV9PUEVSQU5EIChhcmcxLCAxKSkpOwoJICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBMU0hJRlRfRVhQUgoJICAgICAgJiYgaW50ZWdlcl9vbmVwIChUUkVFX09QRVJBTkQgKGFyZzAsIDApKSkKCSAgICByZXR1cm4gZm9sZCAoYnVpbGQgKExTSElGVF9FWFBSLCB0eXBlLCBhcmcxLAoJCQkJVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkpOwoKCSAgaWYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QKCSAgICAgICYmIDAgIT0gKHRlbSA9IGV4dHJhY3RfbXVsZGl2IChUUkVFX09QRVJBTkQgKHQsIDApLAoJCQkJCSAgICAgZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcxKSwKCQkJCQkgICAgIGNvZGUsIE5VTExfVFJFRSkpKQoJICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIHRlbSk7CgoJfQogICAgICBlbHNlCgl7CgkgIC8qIE1heWJlIGZvbGQgeCAqIDAgdG8gMC4gIFRoZSBleHByZXNzaW9ucyBhcmVuJ3QgdGhlIHNhbWUKCSAgICAgd2hlbiB4IGlzIE5hTiwgc2luY2UgeCAqIDAgaXMgYWxzbyBOYU4uICBOb3IgYXJlIHRoZXkgdGhlCgkgICAgIHNhbWUgaW4gbW9kZXMgd2l0aCBzaWduZWQgemVyb3MsIHNpbmNlIG11bHRpcGx5aW5nIGEKCSAgICAgbmVnYXRpdmUgdmFsdWUgYnkgMCBnaXZlcyAtMCwgbm90ICswLiAgKi8KCSAgaWYgKCFIT05PUl9OQU5TIChUWVBFX01PREUgKFRSRUVfVFlQRSAoYXJnMCkpKQoJICAgICAgJiYgIUhPTk9SX1NJR05FRF9aRVJPUyAoVFlQRV9NT0RFIChUUkVFX1RZUEUgKGFyZzApKSkKCSAgICAgICYmIHJlYWxfemVyb3AgKGFyZzEpKQoJICAgIHJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLCBhcmcxLCBhcmcwKTsKCSAgLyogSW4gSUVFRSBmbG9hdGluZyBwb2ludCwgeCoxIGlzIG5vdCBlcXVpdmFsZW50IHRvIHggZm9yIHNuYW5zLiAgKi8KCSAgaWYgKCFIT05PUl9TTkFOUyAoVFlQRV9NT0RFIChUUkVFX1RZUEUgKGFyZzApKSkKCSAgICAgICYmIHJlYWxfb25lcCAoYXJnMSkpCgkgICAgcmV0dXJuIG5vbl9sdmFsdWUgKGZvbGRfY29udmVydCAodHlwZSwgYXJnMCkpOwoKCSAgLyogVHJhbnNmb3JtIHggKiAtMS4wIGludG8gLXguICAqLwoJICBpZiAoIUhPTk9SX1NOQU5TIChUWVBFX01PREUgKFRSRUVfVFlQRSAoYXJnMCkpKQoJICAgICAgJiYgcmVhbF9taW51c19vbmVwIChhcmcxKSkKCSAgICByZXR1cm4gZm9sZCAoYnVpbGQxIChORUdBVEVfRVhQUiwgdHlwZSwgYXJnMCkpOwoKCSAgLyogQ29udmVydCAoQzEvWCkqQzIgaW50byAoQzEqQzIpL1guICAqLwoJICBpZiAoZmxhZ191bnNhZmVfbWF0aF9vcHRpbWl6YXRpb25zCgkgICAgICAmJiBUUkVFX0NPREUgKGFyZzApID09IFJESVZfRVhQUgoJICAgICAgJiYgVFJFRV9DT0RFIChhcmcxKSA9PSBSRUFMX0NTVAoJICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzAsIDApKSA9PSBSRUFMX0NTVCkKCSAgICB7CgkgICAgICB0cmVlIHRlbSA9IGNvbnN0X2Jpbm9wIChNVUxUX0VYUFIsIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksCgkJCQkgICAgICBhcmcxLCAwKTsKCSAgICAgIGlmICh0ZW0pCgkJcmV0dXJuIGZvbGQgKGJ1aWxkIChSRElWX0VYUFIsIHR5cGUsIHRlbSwKCQkJCSAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSk7CgkgICAgfQoKCSAgaWYgKGZsYWdfdW5zYWZlX21hdGhfb3B0aW1pemF0aW9ucykKCSAgICB7CgkgICAgICBlbnVtIGJ1aWx0X2luX2Z1bmN0aW9uIGZjb2RlMCA9IGJ1aWx0aW5fbWF0aGZuX2NvZGUgKGFyZzApOwoJICAgICAgZW51bSBidWlsdF9pbl9mdW5jdGlvbiBmY29kZTEgPSBidWlsdGluX21hdGhmbl9jb2RlIChhcmcxKTsKCgkgICAgICAvKiBPcHRpbWl6YXRpb25zIG9mIHNxcnQoLi4uKSpzcXJ0KC4uLikuICAqLwoJICAgICAgaWYgKChmY29kZTAgPT0gQlVJTFRfSU5fU1FSVCAmJiBmY29kZTEgPT0gQlVJTFRfSU5fU1FSVCkKCQkgIHx8IChmY29kZTAgPT0gQlVJTFRfSU5fU1FSVEYgJiYgZmNvZGUxID09IEJVSUxUX0lOX1NRUlRGKQoJCSAgfHwgKGZjb2RlMCA9PSBCVUlMVF9JTl9TUVJUTCAmJiBmY29kZTEgPT0gQlVJTFRfSU5fU1FSVEwpKQoJCXsKCQkgIHRyZWUgc3FydGZuLCBhcmcsIGFyZ2xpc3Q7CgkJICB0cmVlIGFyZzAwID0gVFJFRV9WQUxVRSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSk7CgkJICB0cmVlIGFyZzEwID0gVFJFRV9WQUxVRSAoVFJFRV9PUEVSQU5EIChhcmcxLCAxKSk7CgoJCSAgLyogT3B0aW1pemUgc3FydCh4KSpzcXJ0KHgpIGFzIHguICAqLwoJCSAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoYXJnMDAsIGFyZzEwLCAwKQoJCSAgICAgICYmICEgSE9OT1JfU05BTlMgKFRZUEVfTU9ERSAodHlwZSkpKQoJCSAgICByZXR1cm4gYXJnMDA7CgoJICAgICAgICAgIC8qIE9wdGltaXplIHNxcnQoeCkqc3FydCh5KSBhcyBzcXJ0KHgqeSkuICAqLwoJCSAgc3FydGZuID0gVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLCAwKTsKCQkgIGFyZyA9IGZvbGQgKGJ1aWxkIChNVUxUX0VYUFIsIHR5cGUsIGFyZzAwLCBhcmcxMCkpOwoJCSAgYXJnbGlzdCA9IGJ1aWxkX3RyZWVfbGlzdCAoTlVMTF9UUkVFLCBhcmcpOwoJCSAgcmV0dXJuIGJ1aWxkX2Z1bmN0aW9uX2NhbGxfZXhwciAoc3FydGZuLCBhcmdsaXN0KTsKCQl9CgoJICAgICAgLyogT3B0aW1pemUgZXhwTih4KSpleHBOKHkpIGFzIGV4cE4oeCt5KS4gICovCgkgICAgICBpZiAoZmNvZGUwID09IGZjb2RlMQoJCSAgJiYgKGZjb2RlMCA9PSBCVUlMVF9JTl9FWFAKCQkgICAgICB8fCBmY29kZTAgPT0gQlVJTFRfSU5fRVhQRgoJCSAgICAgIHx8IGZjb2RlMCA9PSBCVUlMVF9JTl9FWFBMCgkJICAgICAgfHwgZmNvZGUwID09IEJVSUxUX0lOX0VYUDIKCQkgICAgICB8fCBmY29kZTAgPT0gQlVJTFRfSU5fRVhQMkYKCQkgICAgICB8fCBmY29kZTAgPT0gQlVJTFRfSU5fRVhQMkwKCQkgICAgICB8fCBmY29kZTAgPT0gQlVJTFRfSU5fRVhQMTAKCQkgICAgICB8fCBmY29kZTAgPT0gQlVJTFRfSU5fRVhQMTBGCgkJICAgICAgfHwgZmNvZGUwID09IEJVSUxUX0lOX0VYUDEwTAoJCSAgICAgIHx8IGZjb2RlMCA9PSBCVUlMVF9JTl9QT1cxMAoJCSAgICAgIHx8IGZjb2RlMCA9PSBCVUlMVF9JTl9QT1cxMEYKCQkgICAgICB8fCBmY29kZTAgPT0gQlVJTFRfSU5fUE9XMTBMKSkKCQl7CgkJICB0cmVlIGV4cGZuID0gVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLCAwKTsKCQkgIHRyZWUgYXJnID0gYnVpbGQgKFBMVVNfRVhQUiwgdHlwZSwKCQkJCSAgICBUUkVFX1ZBTFVFIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSwKCQkJCSAgICBUUkVFX1ZBTFVFIChUUkVFX09QRVJBTkQgKGFyZzEsIDEpKSk7CgkJICB0cmVlIGFyZ2xpc3QgPSBidWlsZF90cmVlX2xpc3QgKE5VTExfVFJFRSwgZm9sZCAoYXJnKSk7CgkJICByZXR1cm4gYnVpbGRfZnVuY3Rpb25fY2FsbF9leHByIChleHBmbiwgYXJnbGlzdCk7CgkJfQoKCSAgICAgIC8qIE9wdGltaXphdGlvbnMgb2YgcG93KC4uLikqcG93KC4uLikuICAqLwoJICAgICAgaWYgKChmY29kZTAgPT0gQlVJTFRfSU5fUE9XICYmIGZjb2RlMSA9PSBCVUlMVF9JTl9QT1cpCgkJICB8fCAoZmNvZGUwID09IEJVSUxUX0lOX1BPV0YgJiYgZmNvZGUxID09IEJVSUxUX0lOX1BPV0YpCgkJICB8fCAoZmNvZGUwID09IEJVSUxUX0lOX1BPV0wgJiYgZmNvZGUxID09IEJVSUxUX0lOX1BPV0wpKQoJCXsKCQkgIHRyZWUgYXJnMDAgPSBUUkVFX1ZBTFVFIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKTsKCQkgIHRyZWUgYXJnMDEgPSBUUkVFX1ZBTFVFIChUUkVFX0NIQUlOIChUUkVFX09QRVJBTkQgKGFyZzAsCgkJCQkJCQkJICAgICAxKSkpOwoJCSAgdHJlZSBhcmcxMCA9IFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpOwoJCSAgdHJlZSBhcmcxMSA9IFRSRUVfVkFMVUUgKFRSRUVfQ0hBSU4gKFRSRUVfT1BFUkFORCAoYXJnMSwKCQkJCQkJCQkgICAgIDEpKSk7CgoJCSAgLyogT3B0aW1pemUgcG93KHgseSkqcG93KHoseSkgYXMgcG93KHgqeix5KS4gICovCgkJICBpZiAob3BlcmFuZF9lcXVhbF9wIChhcmcwMSwgYXJnMTEsIDApKQoJCSAgICB7CgkJICAgICAgdHJlZSBwb3dmbiA9IFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgMCk7CgkJICAgICAgdHJlZSBhcmcgPSBidWlsZCAoTVVMVF9FWFBSLCB0eXBlLCBhcmcwMCwgYXJnMTApOwoJCSAgICAgIHRyZWUgYXJnbGlzdCA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBmb2xkIChhcmcpLAoJCQkJCQlidWlsZF90cmVlX2xpc3QgKE5VTExfVFJFRSwKCQkJCQkJCQkgYXJnMDEpKTsKCQkgICAgICByZXR1cm4gYnVpbGRfZnVuY3Rpb25fY2FsbF9leHByIChwb3dmbiwgYXJnbGlzdCk7CgkJICAgIH0KCgkJICAvKiBPcHRpbWl6ZSBwb3coeCx5KSpwb3coeCx6KSBhcyBwb3coeCx5K3opLiAgKi8KCQkgIGlmIChvcGVyYW5kX2VxdWFsX3AgKGFyZzAwLCBhcmcxMCwgMCkpCgkJICAgIHsKCQkgICAgICB0cmVlIHBvd2ZuID0gVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLCAwKTsKCQkgICAgICB0cmVlIGFyZyA9IGZvbGQgKGJ1aWxkIChQTFVTX0VYUFIsIHR5cGUsIGFyZzAxLCBhcmcxMSkpOwoJCSAgICAgIHRyZWUgYXJnbGlzdCA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBhcmcwMCwKCQkJCQkJYnVpbGRfdHJlZV9saXN0IChOVUxMX1RSRUUsCgkJCQkJCQkJIGFyZykpOwoJCSAgICAgIHJldHVybiBidWlsZF9mdW5jdGlvbl9jYWxsX2V4cHIgKHBvd2ZuLCBhcmdsaXN0KTsKCQkgICAgfQoJCX0KCgkgICAgICAvKiBPcHRpbWl6ZSB0YW4oeCkqY29zKHgpIGFzIHNpbih4KS4gICovCgkgICAgICBpZiAoKChmY29kZTAgPT0gQlVJTFRfSU5fVEFOICYmIGZjb2RlMSA9PSBCVUlMVF9JTl9DT1MpCgkJICAgfHwgKGZjb2RlMCA9PSBCVUlMVF9JTl9UQU5GICYmIGZjb2RlMSA9PSBCVUlMVF9JTl9DT1NGKQoJCSAgIHx8IChmY29kZTAgPT0gQlVJTFRfSU5fVEFOTCAmJiBmY29kZTEgPT0gQlVJTFRfSU5fQ09TTCkKCQkgICB8fCAoZmNvZGUwID09IEJVSUxUX0lOX0NPUyAmJiBmY29kZTEgPT0gQlVJTFRfSU5fVEFOKQoJCSAgIHx8IChmY29kZTAgPT0gQlVJTFRfSU5fQ09TRiAmJiBmY29kZTEgPT0gQlVJTFRfSU5fVEFORikKCQkgICB8fCAoZmNvZGUwID09IEJVSUxUX0lOX0NPU0wgJiYgZmNvZGUxID09IEJVSUxUX0lOX1RBTkwpKQoJCSAgJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX1ZBTFVFIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSwKCQkJCSAgICAgIFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpLCAwKSkKCQl7CgkJICB0cmVlIHNpbmZuOwoKCQkgIHN3aXRjaCAoZmNvZGUwKQoJCSAgICB7CgkJICAgIGNhc2UgQlVJTFRfSU5fVEFOOgoJCSAgICBjYXNlIEJVSUxUX0lOX0NPUzoKCQkgICAgICBzaW5mbiA9IGltcGxpY2l0X2J1aWx0X2luX2RlY2xzW0JVSUxUX0lOX1NJTl07CgkJICAgICAgYnJlYWs7CgkJICAgIGNhc2UgQlVJTFRfSU5fVEFORjoKCQkgICAgY2FzZSBCVUlMVF9JTl9DT1NGOgoJCSAgICAgIHNpbmZuID0gaW1wbGljaXRfYnVpbHRfaW5fZGVjbHNbQlVJTFRfSU5fU0lORl07CgkJICAgICAgYnJlYWs7CgkJICAgIGNhc2UgQlVJTFRfSU5fVEFOTDoKCQkgICAgY2FzZSBCVUlMVF9JTl9DT1NMOgoJCSAgICAgIHNpbmZuID0gaW1wbGljaXRfYnVpbHRfaW5fZGVjbHNbQlVJTFRfSU5fU0lOTF07CgkJICAgICAgYnJlYWs7CgkJICAgIGRlZmF1bHQ6CgkJICAgICAgc2luZm4gPSBOVUxMX1RSRUU7CgkJICAgIH0KCgkJICBpZiAoc2luZm4gIT0gTlVMTF9UUkVFKQoJCSAgICByZXR1cm4gYnVpbGRfZnVuY3Rpb25fY2FsbF9leHByIChzaW5mbiwKCQkJCQkJICAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDEpKTsKCQl9CgoJICAgICAgLyogT3B0aW1pemUgeCpwb3coeCxjKSBhcyBwb3coeCxjKzEpLiAgKi8KCSAgICAgIGlmIChmY29kZTEgPT0gQlVJTFRfSU5fUE9XCgkJICB8fCBmY29kZTEgPT0gQlVJTFRfSU5fUE9XRgoJCSAgfHwgZmNvZGUxID09IEJVSUxUX0lOX1BPV0wpCgkJewoJCSAgdHJlZSBhcmcxMCA9IFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpOwoJCSAgdHJlZSBhcmcxMSA9IFRSRUVfVkFMVUUgKFRSRUVfQ0hBSU4gKFRSRUVfT1BFUkFORCAoYXJnMSwKCQkJCQkJCQkgICAgIDEpKSk7CgkJICBpZiAoVFJFRV9DT0RFIChhcmcxMSkgPT0gUkVBTF9DU1QKCQkgICAgICAmJiAhIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKGFyZzExKQoJCSAgICAgICYmIG9wZXJhbmRfZXF1YWxfcCAoYXJnMCwgYXJnMTAsIDApKQoJCSAgICB7CgkJICAgICAgdHJlZSBwb3dmbiA9IFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EIChhcmcxLCAwKSwgMCk7CgkJICAgICAgUkVBTF9WQUxVRV9UWVBFIGM7CgkJICAgICAgdHJlZSBhcmcsIGFyZ2xpc3Q7CgoJCSAgICAgIGMgPSBUUkVFX1JFQUxfQ1NUIChhcmcxMSk7CgkJICAgICAgcmVhbF9hcml0aG1ldGljICgmYywgUExVU19FWFBSLCAmYywgJmRjb25zdDEpOwoJCSAgICAgIGFyZyA9IGJ1aWxkX3JlYWwgKHR5cGUsIGMpOwoJCSAgICAgIGFyZ2xpc3QgPSBidWlsZF90cmVlX2xpc3QgKE5VTExfVFJFRSwgYXJnKTsKCQkgICAgICBhcmdsaXN0ID0gdHJlZV9jb25zIChOVUxMX1RSRUUsIGFyZzAsIGFyZ2xpc3QpOwoJCSAgICAgIHJldHVybiBidWlsZF9mdW5jdGlvbl9jYWxsX2V4cHIgKHBvd2ZuLCBhcmdsaXN0KTsKCQkgICAgfQoJCX0KCgkgICAgICAvKiBPcHRpbWl6ZSBwb3coeCxjKSp4IGFzIHBvdyh4LGMrMSkuICAqLwoJICAgICAgaWYgKGZjb2RlMCA9PSBCVUlMVF9JTl9QT1cKCQkgIHx8IGZjb2RlMCA9PSBCVUlMVF9JTl9QT1dGCgkJICB8fCBmY29kZTAgPT0gQlVJTFRfSU5fUE9XTCkKCQl7CgkJICB0cmVlIGFyZzAwID0gVFJFRV9WQUxVRSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSk7CgkJICB0cmVlIGFyZzAxID0gVFJFRV9WQUxVRSAoVFJFRV9DSEFJTiAoVFJFRV9PUEVSQU5EIChhcmcwLAoJCQkJCQkJCSAgICAgMSkpKTsKCQkgIGlmIChUUkVFX0NPREUgKGFyZzAxKSA9PSBSRUFMX0NTVAoJCSAgICAgICYmICEgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAoYXJnMDEpCgkJICAgICAgJiYgb3BlcmFuZF9lcXVhbF9wIChhcmcxLCBhcmcwMCwgMCkpCgkJICAgIHsKCQkgICAgICB0cmVlIHBvd2ZuID0gVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKGFyZzAsIDApLCAwKTsKCQkgICAgICBSRUFMX1ZBTFVFX1RZUEUgYzsKCQkgICAgICB0cmVlIGFyZywgYXJnbGlzdDsKCgkJICAgICAgYyA9IFRSRUVfUkVBTF9DU1QgKGFyZzAxKTsKCQkgICAgICByZWFsX2FyaXRobWV0aWMgKCZjLCBQTFVTX0VYUFIsICZjLCAmZGNvbnN0MSk7CgkJICAgICAgYXJnID0gYnVpbGRfcmVhbCAodHlwZSwgYyk7CgkJICAgICAgYXJnbGlzdCA9IGJ1aWxkX3RyZWVfbGlzdCAoTlVMTF9UUkVFLCBhcmcpOwoJCSAgICAgIGFyZ2xpc3QgPSB0cmVlX2NvbnMgKE5VTExfVFJFRSwgYXJnMSwgYXJnbGlzdCk7CgkJICAgICAgcmV0dXJuIGJ1aWxkX2Z1bmN0aW9uX2NhbGxfZXhwciAocG93Zm4sIGFyZ2xpc3QpOwoJCSAgICB9CgkJfQoKCSAgICAgIC8qIE9wdGltaXplIHgqeCBhcyBwb3coeCwyLjApLCB3aGljaCBpcyBleHBhbmRlZCBhcyB4KnguICAqLwoJICAgICAgaWYgKCEgb3B0aW1pemVfc2l6ZQoJCSAgJiYgb3BlcmFuZF9lcXVhbF9wIChhcmcwLCBhcmcxLCAwKSkKCQl7CgkJICB0cmVlIHBvd2ZuOwoKCQkgIGlmICh0eXBlID09IGRvdWJsZV90eXBlX25vZGUpCgkJICAgIHBvd2ZuID0gaW1wbGljaXRfYnVpbHRfaW5fZGVjbHNbQlVJTFRfSU5fUE9XXTsKCQkgIGVsc2UgaWYgKHR5cGUgPT0gZmxvYXRfdHlwZV9ub2RlKQoJCSAgICBwb3dmbiA9IGltcGxpY2l0X2J1aWx0X2luX2RlY2xzW0JVSUxUX0lOX1BPV0ZdOwoJCSAgZWxzZSBpZiAodHlwZSA9PSBsb25nX2RvdWJsZV90eXBlX25vZGUpCgkJICAgIHBvd2ZuID0gaW1wbGljaXRfYnVpbHRfaW5fZGVjbHNbQlVJTFRfSU5fUE9XTF07CgkJICBlbHNlCgkJICAgIHBvd2ZuID0gTlVMTF9UUkVFOwoKCQkgIGlmIChwb3dmbikKCQkgICAgewoJCSAgICAgIHRyZWUgYXJnID0gYnVpbGRfcmVhbCAodHlwZSwgZGNvbnN0Mik7CgkJICAgICAgdHJlZSBhcmdsaXN0ID0gYnVpbGRfdHJlZV9saXN0IChOVUxMX1RSRUUsIGFyZyk7CgkJICAgICAgYXJnbGlzdCA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBhcmcwLCBhcmdsaXN0KTsKCQkgICAgICByZXR1cm4gYnVpbGRfZnVuY3Rpb25fY2FsbF9leHByIChwb3dmbiwgYXJnbGlzdCk7CgkJICAgIH0KCQl9CgkgICAgfQoJfQogICAgICBnb3RvIGFzc29jaWF0ZTsKCiAgICBjYXNlIEJJVF9JT1JfRVhQUjoKICAgIGJpdF9pb3I6CiAgICAgIGlmIChpbnRlZ2VyX2FsbF9vbmVzcCAoYXJnMSkpCglyZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgYXJnMSwgYXJnMCk7CiAgICAgIGlmIChpbnRlZ2VyX3plcm9wIChhcmcxKSkKCXJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzApKTsKICAgICAgdDEgPSBkaXN0cmlidXRlX2JpdF9leHByIChjb2RlLCB0eXBlLCBhcmcwLCBhcmcxKTsKICAgICAgaWYgKHQxICE9IE5VTExfVFJFRSkKCXJldHVybiB0MTsKCiAgICAgIC8qIENvbnZlcnQgKG9yIChub3QgYXJnMCkgKG5vdCBhcmcxKSkgdG8gKG5vdCAoYW5kIChhcmcwKSAoYXJnMSkpKS4KCgkgVGhpcyByZXN1bHRzIGluIG1vcmUgZWZmaWNpZW50IGNvZGUgZm9yIG1hY2hpbmVzIHdpdGhvdXQgYSBOQU5ECgkgaW5zdHJ1Y3Rpb24uICBDb21iaW5lIHdpbGwgY2Fub25pY2FsaXplIHRvIHRoZSBmaXJzdCBmb3JtCgkgd2hpY2ggd2lsbCBhbGxvdyB1c2Ugb2YgTkFORCBpbnN0cnVjdGlvbnMgcHJvdmlkZWQgYnkgdGhlCgkgYmFja2VuZCBpZiB0aGV5IGV4aXN0LiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQklUX05PVF9FWFBSCgkgICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gQklUX05PVF9FWFBSKQoJewoJICByZXR1cm4gZm9sZCAoYnVpbGQxIChCSVRfTk9UX0VYUFIsIHR5cGUsCgkJCSAgICAgICBidWlsZCAoQklUX0FORF9FWFBSLCB0eXBlLAoJCQkJICAgICAgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwKCQkJCSAgICAgIFRSRUVfT1BFUkFORCAoYXJnMSwgMCkpKSk7Cgl9CgogICAgICAvKiBTZWUgaWYgdGhpcyBjYW4gYmUgc2ltcGxpZmllZCBpbnRvIGEgcm90YXRlIGZpcnN0LiAgSWYgdGhhdAoJIGlzIHVuc3VjY2Vzc2Z1bCBjb250aW51ZSBpbiB0aGUgYXNzb2NpYXRpb24gY29kZS4gICovCiAgICAgIGdvdG8gYml0X3JvdGF0ZTsKCiAgICBjYXNlIEJJVF9YT1JfRVhQUjoKICAgICAgaWYgKGludGVnZXJfemVyb3AgKGFyZzEpKQoJcmV0dXJuIG5vbl9sdmFsdWUgKGZvbGRfY29udmVydCAodHlwZSwgYXJnMCkpOwogICAgICBpZiAoaW50ZWdlcl9hbGxfb25lc3AgKGFyZzEpKQoJcmV0dXJuIGZvbGQgKGJ1aWxkMSAoQklUX05PVF9FWFBSLCB0eXBlLCBhcmcwKSk7CgogICAgICAvKiBJZiB3ZSBhcmUgWE9SaW5nIHR3byBCSVRfQU5EX0VYUFIncywgYm90aCBvZiB3aGljaCBhcmUgYW5kJ2luZwogICAgICAgICB3aXRoIGEgY29uc3RhbnQsIGFuZCB0aGUgdHdvIGNvbnN0YW50cyBoYXZlIG5vIGJpdHMgaW4gY29tbW9uLAoJIHdlIHNob3VsZCB0cmVhdCB0aGlzIGFzIGEgQklUX0lPUl9FWFBSIHNpbmNlIHRoaXMgbWF5IHByb2R1Y2UgbW9yZQoJIHNpbXBsaWZpY2F0aW9ucy4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzApID09IEJJVF9BTkRfRVhQUgoJICAmJiBUUkVFX0NPREUgKGFyZzEpID09IEJJVF9BTkRfRVhQUgoJICAmJiBUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpID09IElOVEVHRVJfQ1NUCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcxLCAxKSkgPT0gSU5URUdFUl9DU1QKCSAgJiYgaW50ZWdlcl96ZXJvcCAoY29uc3RfYmlub3AgKEJJVF9BTkRfRVhQUiwKCQkJCQkgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwKCQkJCQkgVFJFRV9PUEVSQU5EIChhcmcxLCAxKSwgMCkpKQoJewoJICBjb2RlID0gQklUX0lPUl9FWFBSOwoJICBnb3RvIGJpdF9pb3I7Cgl9CgogICAgICAvKiBTZWUgaWYgdGhpcyBjYW4gYmUgc2ltcGxpZmllZCBpbnRvIGEgcm90YXRlIGZpcnN0LiAgSWYgdGhhdAoJIGlzIHVuc3VjY2Vzc2Z1bCBjb250aW51ZSBpbiB0aGUgYXNzb2NpYXRpb24gY29kZS4gICovCiAgICAgIGdvdG8gYml0X3JvdGF0ZTsKCiAgICBjYXNlIEJJVF9BTkRfRVhQUjoKICAgICAgaWYgKGludGVnZXJfYWxsX29uZXNwIChhcmcxKSkKCXJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzApKTsKICAgICAgaWYgKGludGVnZXJfemVyb3AgKGFyZzEpKQoJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIGFyZzEsIGFyZzApOwogICAgICB0MSA9IGRpc3RyaWJ1dGVfYml0X2V4cHIgKGNvZGUsIHR5cGUsIGFyZzAsIGFyZzEpOwogICAgICBpZiAodDEgIT0gTlVMTF9UUkVFKQoJcmV0dXJuIHQxOwogICAgICAvKiBTaW1wbGlmeSAoKGludCljICYgMDM3NykgaW50byAoaW50KWMsIGlmIGMgaXMgdW5zaWduZWQgY2hhci4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUICYmIFRSRUVfQ09ERSAoYXJnMCkgPT0gTk9QX0VYUFIKCSAgJiYgVFJFRV9VTlNJR05FRCAoVFJFRV9UWVBFIChUUkVFX09QRVJBTkQgKGFyZzAsIDApKSkpCgl7CgkgIHVuc2lnbmVkIGludCBwcmVjCgkgICAgPSBUWVBFX1BSRUNJU0lPTiAoVFJFRV9UWVBFIChUUkVFX09QRVJBTkQgKGFyZzAsIDApKSk7CgoJICBpZiAocHJlYyA8IEJJVFNfUEVSX1dPUkQgJiYgcHJlYyA8IEhPU1RfQklUU19QRVJfV0lERV9JTlQKCSAgICAgICYmICh+VFJFRV9JTlRfQ1NUX0xPVyAoYXJnMSkKCQkgICYgKCgoSE9TVF9XSURFX0lOVCkgMSA8PCBwcmVjKSAtIDEpKSA9PSAwKQoJICAgIHJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnMCwgMCkpOwoJfQoKICAgICAgLyogQ29udmVydCAoYW5kIChub3QgYXJnMCkgKG5vdCBhcmcxKSkgdG8gKG5vdCAob3IgKGFyZzApIChhcmcxKSkpLgoKCSBUaGlzIHJlc3VsdHMgaW4gbW9yZSBlZmZpY2llbnQgY29kZSBmb3IgbWFjaGluZXMgd2l0aG91dCBhIE5PUgoJIGluc3RydWN0aW9uLiAgQ29tYmluZSB3aWxsIGNhbm9uaWNhbGl6ZSB0byB0aGUgZmlyc3QgZm9ybQoJIHdoaWNoIHdpbGwgYWxsb3cgdXNlIG9mIE5PUiBpbnN0cnVjdGlvbnMgcHJvdmlkZWQgYnkgdGhlCgkgYmFja2VuZCBpZiB0aGV5IGV4aXN0LiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQklUX05PVF9FWFBSCgkgICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gQklUX05PVF9FWFBSKQoJewoJICByZXR1cm4gZm9sZCAoYnVpbGQxIChCSVRfTk9UX0VYUFIsIHR5cGUsCgkJCSAgICAgICBidWlsZCAoQklUX0lPUl9FWFBSLCB0eXBlLAoJCQkJICAgICAgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwKCQkJCSAgICAgIFRSRUVfT1BFUkFORCAoYXJnMSwgMCkpKSk7Cgl9CgogICAgICBnb3RvIGFzc29jaWF0ZTsKCiAgICBjYXNlIFJESVZfRVhQUjoKICAgICAgLyogRG9uJ3QgdG91Y2ggYSBmbG9hdGluZy1wb2ludCBkaXZpZGUgYnkgemVybyB1bmxlc3MgdGhlIG1vZGUKCSBvZiB0aGUgY29uc3RhbnQgY2FuIHJlcHJlc2VudCBpbmZpbml0eS4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzEpID09IFJFQUxfQ1NUCgkgICYmICFNT0RFX0hBU19JTkZJTklUSUVTIChUWVBFX01PREUgKFRSRUVfVFlQRSAoYXJnMSkpKQoJICAmJiByZWFsX3plcm9wIChhcmcxKSkKCXJldHVybiB0OwoKICAgICAgLyogKC1BKSAvICgtQikgLT4gQSAvIEIgICovCiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzApID09IE5FR0FURV9FWFBSICYmIG5lZ2F0ZV9leHByX3AgKGFyZzEpKQoJcmV0dXJuIGZvbGQgKGJ1aWxkIChSRElWX0VYUFIsIHR5cGUsCgkJCSAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkgICAgbmVnYXRlX2V4cHIgKGFyZzEpKSk7CiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzEpID09IE5FR0FURV9FWFBSICYmIG5lZ2F0ZV9leHByX3AgKGFyZzApKQoJcmV0dXJuIGZvbGQgKGJ1aWxkIChSRElWX0VYUFIsIHR5cGUsCgkJCSAgICBuZWdhdGVfZXhwciAoYXJnMCksCgkJCSAgICBUUkVFX09QRVJBTkQgKGFyZzEsIDApKSk7CgogICAgICAvKiBJbiBJRUVFIGZsb2F0aW5nIHBvaW50LCB4LzEgaXMgbm90IGVxdWl2YWxlbnQgdG8geCBmb3Igc25hbnMuICAqLwogICAgICBpZiAoIUhPTk9SX1NOQU5TIChUWVBFX01PREUgKFRSRUVfVFlQRSAoYXJnMCkpKQoJICAmJiByZWFsX29uZXAgKGFyZzEpKQoJcmV0dXJuIG5vbl9sdmFsdWUgKGZvbGRfY29udmVydCAodHlwZSwgYXJnMCkpOwoKICAgICAgLyogSW4gSUVFRSBmbG9hdGluZyBwb2ludCwgeC8tMSBpcyBub3QgZXF1aXZhbGVudCB0byAteCBmb3Igc25hbnMuICAqLwogICAgICBpZiAoIUhPTk9SX1NOQU5TIChUWVBFX01PREUgKFRSRUVfVFlQRSAoYXJnMCkpKQoJICAmJiByZWFsX21pbnVzX29uZXAgKGFyZzEpKQoJcmV0dXJuIG5vbl9sdmFsdWUgKGZvbGRfY29udmVydCAodHlwZSwgbmVnYXRlX2V4cHIgKGFyZzApKSk7CgogICAgICAvKiBJZiBBUkcxIGlzIGEgY29uc3RhbnQsIHdlIGNhbiBjb252ZXJ0IHRoaXMgdG8gYSBtdWx0aXBseSBieSB0aGUKCSByZWNpcHJvY2FsLiAgVGhpcyBkb2VzIG5vdCBoYXZlIHRoZSBzYW1lIHJvdW5kaW5nIHByb3BlcnRpZXMsCgkgc28gb25seSBkbyB0aGlzIGlmIC1mdW5zYWZlLW1hdGgtb3B0aW1pemF0aW9ucy4gIFdlIGNhbiBhY3R1YWxseQoJIGFsd2F5cyBzYWZlbHkgZG8gaXQgaWYgQVJHMSBpcyBhIHBvd2VyIG9mIHR3bywgYnV0IGl0J3MgaGFyZCB0bwoJIHRlbGwgaWYgaXQgaXMgb3Igbm90IGluIGEgcG9ydGFibGUgbWFubmVyLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gUkVBTF9DU1QpCgl7CgkgIGlmIChmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMKCSAgICAgICYmIDAgIT0gKHRlbSA9IGNvbnN0X2Jpbm9wIChjb2RlLCBidWlsZF9yZWFsICh0eXBlLCBkY29uc3QxKSwKCQkJCQkgIGFyZzEsIDApKSkKCSAgICByZXR1cm4gZm9sZCAoYnVpbGQgKE1VTFRfRVhQUiwgdHlwZSwgYXJnMCwgdGVtKSk7CgkgIC8qIEZpbmQgdGhlIHJlY2lwcm9jYWwgaWYgb3B0aW1pemluZyBhbmQgdGhlIHJlc3VsdCBpcyBleGFjdC4gICovCgkgIGlmIChvcHRpbWl6ZSkKCSAgICB7CgkgICAgICBSRUFMX1ZBTFVFX1RZUEUgcjsKCSAgICAgIHIgPSBUUkVFX1JFQUxfQ1NUIChhcmcxKTsKCSAgICAgIGlmIChleGFjdF9yZWFsX2ludmVyc2UgKFRZUEVfTU9ERShUUkVFX1RZUEUoYXJnMCkpLCAmcikpCgkJewoJCSAgdGVtID0gYnVpbGRfcmVhbCAodHlwZSwgcik7CgkJICByZXR1cm4gZm9sZCAoYnVpbGQgKE1VTFRfRVhQUiwgdHlwZSwgYXJnMCwgdGVtKSk7CgkJfQoJICAgIH0KCX0KICAgICAgLyogQ29udmVydCBBL0IvQyB0byBBLyhCKkMpLiAgKi8KICAgICAgaWYgKGZsYWdfdW5zYWZlX21hdGhfb3B0aW1pemF0aW9ucwoJICAmJiBUUkVFX0NPREUgKGFyZzApID09IFJESVZfRVhQUikKCXJldHVybiBmb2xkIChidWlsZCAoUkRJVl9FWFBSLCB0eXBlLCBUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkgICAgZm9sZCAoYnVpbGQgKE1VTFRfRVhQUiwgdHlwZSwKCQkJCQkgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwgYXJnMSkpKSk7CgogICAgICAvKiBDb252ZXJ0IEEvKEIvQykgdG8gKEEvQikqQy4gICovCiAgICAgIGlmIChmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMKCSAgJiYgVFJFRV9DT0RFIChhcmcxKSA9PSBSRElWX0VYUFIpCglyZXR1cm4gZm9sZCAoYnVpbGQgKE1VTFRfRVhQUiwgdHlwZSwKCQkJICAgIGZvbGQgKGJ1aWxkIChSRElWX0VYUFIsIHR5cGUsIGFyZzAsCgkJCQkJIFRSRUVfT1BFUkFORCAoYXJnMSwgMCkpKSwKCQkJICAgIFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpKTsKCiAgICAgIC8qIENvbnZlcnQgQzEvKFgqQzIpIGludG8gKEMxL0MyKS9YLiAgKi8KICAgICAgaWYgKGZsYWdfdW5zYWZlX21hdGhfb3B0aW1pemF0aW9ucwoJICAmJiBUUkVFX0NPREUgKGFyZzEpID09IE1VTFRfRVhQUgoJICAmJiBUUkVFX0NPREUgKGFyZzApID09IFJFQUxfQ1NUCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcxLCAxKSkgPT0gUkVBTF9DU1QpCgl7CgkgIHRyZWUgdGVtID0gY29uc3RfYmlub3AgKFJESVZfRVhQUiwgYXJnMCwKCQkJCSAgVFJFRV9PUEVSQU5EIChhcmcxLCAxKSwgMCk7CgkgIGlmICh0ZW0pCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChSRElWX0VYUFIsIHR5cGUsIHRlbSwKCQkJCVRSRUVfT1BFUkFORCAoYXJnMSwgMCkpKTsKCX0KCiAgICAgIGlmIChmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMpCgl7CgkgIGVudW0gYnVpbHRfaW5fZnVuY3Rpb24gZmNvZGUgPSBidWlsdGluX21hdGhmbl9jb2RlIChhcmcxKTsKCSAgLyogT3B0aW1pemUgeC9leHBOKHkpIGludG8geCpleHBOKC15KS4gICovCgkgIGlmIChmY29kZSA9PSBCVUlMVF9JTl9FWFAKCSAgICAgIHx8IGZjb2RlID09IEJVSUxUX0lOX0VYUEYKCSAgICAgIHx8IGZjb2RlID09IEJVSUxUX0lOX0VYUEwKCSAgICAgIHx8IGZjb2RlID09IEJVSUxUX0lOX0VYUDIKCSAgICAgIHx8IGZjb2RlID09IEJVSUxUX0lOX0VYUDJGCgkgICAgICB8fCBmY29kZSA9PSBCVUlMVF9JTl9FWFAyTAoJICAgICAgfHwgZmNvZGUgPT0gQlVJTFRfSU5fRVhQMTAKCSAgICAgIHx8IGZjb2RlID09IEJVSUxUX0lOX0VYUDEwRgoJICAgICAgfHwgZmNvZGUgPT0gQlVJTFRfSU5fRVhQMTBMCgkgICAgICB8fCBmY29kZSA9PSBCVUlMVF9JTl9QT1cxMAoJICAgICAgfHwgZmNvZGUgPT0gQlVJTFRfSU5fUE9XMTBGCgkgICAgICB8fCBmY29kZSA9PSBCVUlMVF9JTl9QT1cxMEwpCgkgICAgewoJICAgICAgdHJlZSBleHBmbiA9IFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EIChhcmcxLCAwKSwgMCk7CgkgICAgICB0cmVlIGFyZyA9IGJ1aWxkMSAoTkVHQVRFX0VYUFIsIHR5cGUsCgkJCQkgVFJFRV9WQUxVRSAoVFJFRV9PUEVSQU5EIChhcmcxLCAxKSkpOwoJICAgICAgdHJlZSBhcmdsaXN0ID0gYnVpbGRfdHJlZV9saXN0IChOVUxMX1RSRUUsIGZvbGQgKGFyZykpOwoJICAgICAgYXJnMSA9IGJ1aWxkX2Z1bmN0aW9uX2NhbGxfZXhwciAoZXhwZm4sIGFyZ2xpc3QpOwoJICAgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChNVUxUX0VYUFIsIHR5cGUsIGFyZzAsIGFyZzEpKTsKCSAgICB9CgoJICAvKiBPcHRpbWl6ZSB4L3Bvdyh5LHopIGludG8geCpwb3coeSwteikuICAqLwoJICBpZiAoZmNvZGUgPT0gQlVJTFRfSU5fUE9XCgkgICAgICB8fCBmY29kZSA9PSBCVUlMVF9JTl9QT1dGCgkgICAgICB8fCBmY29kZSA9PSBCVUlMVF9JTl9QT1dMKQoJICAgIHsKCSAgICAgIHRyZWUgcG93Zm4gPSBUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoYXJnMSwgMCksIDApOwoJICAgICAgdHJlZSBhcmcxMCA9IFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpOwoJICAgICAgdHJlZSBhcmcxMSA9IFRSRUVfVkFMVUUgKFRSRUVfQ0hBSU4gKFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpKTsKCSAgICAgIHRyZWUgbmVnMTEgPSBmb2xkIChidWlsZDEgKE5FR0FURV9FWFBSLCB0eXBlLCBhcmcxMSkpOwoJICAgICAgdHJlZSBhcmdsaXN0ID0gdHJlZV9jb25zKE5VTExfVFJFRSwgYXJnMTAsCgkJCQkgICAgICAgYnVpbGRfdHJlZV9saXN0IChOVUxMX1RSRUUsIG5lZzExKSk7CgkgICAgICBhcmcxID0gYnVpbGRfZnVuY3Rpb25fY2FsbF9leHByIChwb3dmbiwgYXJnbGlzdCk7CgkgICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKE1VTFRfRVhQUiwgdHlwZSwgYXJnMCwgYXJnMSkpOwoJICAgIH0KCX0KCiAgICAgIGlmIChmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMpCgl7CgkgIGVudW0gYnVpbHRfaW5fZnVuY3Rpb24gZmNvZGUwID0gYnVpbHRpbl9tYXRoZm5fY29kZSAoYXJnMCk7CgkgIGVudW0gYnVpbHRfaW5fZnVuY3Rpb24gZmNvZGUxID0gYnVpbHRpbl9tYXRoZm5fY29kZSAoYXJnMSk7CgoJICAvKiBPcHRpbWl6ZSBzaW4oeCkvY29zKHgpIGFzIHRhbih4KS4gICovCgkgIGlmICgoKGZjb2RlMCA9PSBCVUlMVF9JTl9TSU4gJiYgZmNvZGUxID09IEJVSUxUX0lOX0NPUykKCSAgICAgICB8fCAoZmNvZGUwID09IEJVSUxUX0lOX1NJTkYgJiYgZmNvZGUxID09IEJVSUxUX0lOX0NPU0YpCgkgICAgICAgfHwgKGZjb2RlMCA9PSBCVUlMVF9JTl9TSU5MICYmIGZjb2RlMSA9PSBCVUlMVF9JTl9DT1NMKSkKCSAgICAgICYmIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9WQUxVRSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSksCgkJCQkgIFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpLCAwKSkKCSAgICB7CgkgICAgICB0cmVlIHRhbmZuOwoKCSAgICAgIGlmIChmY29kZTAgPT0gQlVJTFRfSU5fU0lOKQoJCXRhbmZuID0gaW1wbGljaXRfYnVpbHRfaW5fZGVjbHNbQlVJTFRfSU5fVEFOXTsKCSAgICAgIGVsc2UgaWYgKGZjb2RlMCA9PSBCVUlMVF9JTl9TSU5GKQoJCXRhbmZuID0gaW1wbGljaXRfYnVpbHRfaW5fZGVjbHNbQlVJTFRfSU5fVEFORl07CgkgICAgICBlbHNlIGlmIChmY29kZTAgPT0gQlVJTFRfSU5fU0lOTCkKCQl0YW5mbiA9IGltcGxpY2l0X2J1aWx0X2luX2RlY2xzW0JVSUxUX0lOX1RBTkxdOwoJICAgICAgZWxzZQoJCXRhbmZuID0gTlVMTF9UUkVFOwoKCSAgICAgIGlmICh0YW5mbiAhPSBOVUxMX1RSRUUpCgkJcmV0dXJuIGJ1aWxkX2Z1bmN0aW9uX2NhbGxfZXhwciAodGFuZm4sCgkJCQkJCSBUUkVFX09QRVJBTkQgKGFyZzAsIDEpKTsKCSAgICB9CgoJICAvKiBPcHRpbWl6ZSBjb3MoeCkvc2luKHgpIGFzIDEuMC90YW4oeCkuICAqLwoJICBpZiAoKChmY29kZTAgPT0gQlVJTFRfSU5fQ09TICYmIGZjb2RlMSA9PSBCVUlMVF9JTl9TSU4pCgkgICAgICAgfHwgKGZjb2RlMCA9PSBCVUlMVF9JTl9DT1NGICYmIGZjb2RlMSA9PSBCVUlMVF9JTl9TSU5GKQoJICAgICAgIHx8IChmY29kZTAgPT0gQlVJTFRfSU5fQ09TTCAmJiBmY29kZTEgPT0gQlVJTFRfSU5fU0lOTCkpCgkgICAgICAmJiBvcGVyYW5kX2VxdWFsX3AgKFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpLAoJCQkJICBUUkVFX1ZBTFVFIChUUkVFX09QRVJBTkQgKGFyZzEsIDEpKSwgMCkpCgkgICAgewoJICAgICAgdHJlZSB0YW5mbjsKCgkgICAgICBpZiAoZmNvZGUwID09IEJVSUxUX0lOX0NPUykKCQl0YW5mbiA9IGltcGxpY2l0X2J1aWx0X2luX2RlY2xzW0JVSUxUX0lOX1RBTl07CgkgICAgICBlbHNlIGlmIChmY29kZTAgPT0gQlVJTFRfSU5fQ09TRikKCQl0YW5mbiA9IGltcGxpY2l0X2J1aWx0X2luX2RlY2xzW0JVSUxUX0lOX1RBTkZdOwoJICAgICAgZWxzZSBpZiAoZmNvZGUwID09IEJVSUxUX0lOX0NPU0wpCgkJdGFuZm4gPSBpbXBsaWNpdF9idWlsdF9pbl9kZWNsc1tCVUlMVF9JTl9UQU5MXTsKCSAgICAgIGVsc2UKCQl0YW5mbiA9IE5VTExfVFJFRTsKCgkgICAgICBpZiAodGFuZm4gIT0gTlVMTF9UUkVFKQoJCXsKCQkgIHRyZWUgdG1wID0gVFJFRV9PUEVSQU5EIChhcmcwLCAxKTsKCQkgIHRtcCA9IGJ1aWxkX2Z1bmN0aW9uX2NhbGxfZXhwciAodGFuZm4sIHRtcCk7CgkJICByZXR1cm4gZm9sZCAoYnVpbGQgKFJESVZfRVhQUiwgdHlwZSwKCQkJCSAgICAgIGJ1aWxkX3JlYWwgKHR5cGUsIGRjb25zdDEpLAoJCQkJICAgICAgdG1wKSk7CgkJfQoJICAgIH0KCgkgIC8qIE9wdGltaXplIHBvdyh4LGMpL3ggYXMgcG93KHgsYy0xKS4gICovCgkgIGlmIChmY29kZTAgPT0gQlVJTFRfSU5fUE9XCgkgICAgICB8fCBmY29kZTAgPT0gQlVJTFRfSU5fUE9XRgoJICAgICAgfHwgZmNvZGUwID09IEJVSUxUX0lOX1BPV0wpCgkgICAgewoJICAgICAgdHJlZSBhcmcwMCA9IFRSRUVfVkFMVUUgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpOwoJICAgICAgdHJlZSBhcmcwMSA9IFRSRUVfVkFMVUUgKFRSRUVfQ0hBSU4gKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpKTsKCSAgICAgIGlmIChUUkVFX0NPREUgKGFyZzAxKSA9PSBSRUFMX0NTVAoJCSAgJiYgISBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcwMSkKCQkgICYmIG9wZXJhbmRfZXF1YWxfcCAoYXJnMSwgYXJnMDAsIDApKQoJCXsKCQkgIHRyZWUgcG93Zm4gPSBUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoYXJnMCwgMCksIDApOwoJCSAgUkVBTF9WQUxVRV9UWVBFIGM7CgkJICB0cmVlIGFyZywgYXJnbGlzdDsKCgkJICBjID0gVFJFRV9SRUFMX0NTVCAoYXJnMDEpOwoJCSAgcmVhbF9hcml0aG1ldGljICgmYywgTUlOVVNfRVhQUiwgJmMsICZkY29uc3QxKTsKCQkgIGFyZyA9IGJ1aWxkX3JlYWwgKHR5cGUsIGMpOwoJCSAgYXJnbGlzdCA9IGJ1aWxkX3RyZWVfbGlzdCAoTlVMTF9UUkVFLCBhcmcpOwoJCSAgYXJnbGlzdCA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBhcmcxLCBhcmdsaXN0KTsKCQkgIHJldHVybiBidWlsZF9mdW5jdGlvbl9jYWxsX2V4cHIgKHBvd2ZuLCBhcmdsaXN0KTsKCQl9CgkgICAgfQoJfQogICAgICBnb3RvIGJpbmFyeTsKCiAgICBjYXNlIFRSVU5DX0RJVl9FWFBSOgogICAgY2FzZSBST1VORF9ESVZfRVhQUjoKICAgIGNhc2UgRkxPT1JfRElWX0VYUFI6CiAgICBjYXNlIENFSUxfRElWX0VYUFI6CiAgICBjYXNlIEVYQUNUX0RJVl9FWFBSOgogICAgICBpZiAoaW50ZWdlcl9vbmVwIChhcmcxKSkKCXJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzApKTsKICAgICAgaWYgKGludGVnZXJfemVyb3AgKGFyZzEpKQoJcmV0dXJuIHQ7CgogICAgICAvKiBJZiBhcmcwIGlzIGEgbXVsdGlwbGUgb2YgYXJnMSwgdGhlbiByZXdyaXRlIHRvIHRoZSBmYXN0ZXN0IGRpdgoJIG9wZXJhdGlvbiwgRVhBQ1RfRElWX0VYUFIuCgoJIE5vdGUgdGhhdCBvbmx5IENFSUxfRElWX0VYUFIgYW5kIEZMT09SX0RJVl9FWFBSIGFyZSByZXdyaXR0ZW4gbm93LgoJIEF0IG9uZSB0aW1lIG90aGVycyBnZW5lcmF0ZWQgZmFzdGVyIGNvZGUsIGl0J3Mgbm90IGNsZWFyIGlmIHRoZXkgZG8KCSBhZnRlciB0aGUgbGFzdCByb3VuZCB0byBjaGFuZ2VzIHRvIHRoZSBESVYgY29kZSBpbiBleHBtZWQuYy4gICovCiAgICAgIGlmICgoY29kZSA9PSBDRUlMX0RJVl9FWFBSIHx8IGNvZGUgPT0gRkxPT1JfRElWX0VYUFIpCgkgICYmIG11bHRpcGxlX29mX3AgKHR5cGUsIGFyZzAsIGFyZzEpKQoJcmV0dXJuIGZvbGQgKGJ1aWxkIChFWEFDVF9ESVZfRVhQUiwgdHlwZSwgYXJnMCwgYXJnMSkpOwoKICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QKCSAgJiYgMCAhPSAodGVtID0gZXh0cmFjdF9tdWxkaXYgKFRSRUVfT1BFUkFORCAodCwgMCksIGFyZzEsCgkJCQkJIGNvZGUsIE5VTExfVFJFRSkpKQoJcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgdGVtKTsKCiAgICAgIGdvdG8gYmluYXJ5OwoKICAgIGNhc2UgQ0VJTF9NT0RfRVhQUjoKICAgIGNhc2UgRkxPT1JfTU9EX0VYUFI6CiAgICBjYXNlIFJPVU5EX01PRF9FWFBSOgogICAgY2FzZSBUUlVOQ19NT0RfRVhQUjoKICAgICAgaWYgKGludGVnZXJfb25lcCAoYXJnMSkpCglyZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgaW50ZWdlcl96ZXJvX25vZGUsIGFyZzApOwogICAgICBpZiAoaW50ZWdlcl96ZXJvcCAoYXJnMSkpCglyZXR1cm4gdDsKCiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUCgkgICYmIDAgIT0gKHRlbSA9IGV4dHJhY3RfbXVsZGl2IChUUkVFX09QRVJBTkQgKHQsIDApLCBhcmcxLAoJCQkJCSBjb2RlLCBOVUxMX1RSRUUpKSkKCXJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIHRlbSk7CgogICAgICBnb3RvIGJpbmFyeTsKCiAgICBjYXNlIExST1RBVEVfRVhQUjoKICAgIGNhc2UgUlJPVEFURV9FWFBSOgogICAgICBpZiAoaW50ZWdlcl9hbGxfb25lc3AgKGFyZzApKQoJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIGFyZzAsIGFyZzEpOwogICAgICBnb3RvIHNoaWZ0OwoKICAgIGNhc2UgUlNISUZUX0VYUFI6CiAgICAgIC8qIE9wdGltaXplIC0xID4+IHggZm9yIGFyaXRobWV0aWMgcmlnaHQgc2hpZnRzLiAgKi8KICAgICAgaWYgKGludGVnZXJfYWxsX29uZXNwIChhcmcwKSAmJiAhIFRSRUVfVU5TSUdORUQgKHR5cGUpKQoJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIGFyZzAsIGFyZzEpOwogICAgICAvKiAuLi4gZmFsbCB0aHJvdWdoIC4uLiAgKi8KCiAgICBjYXNlIExTSElGVF9FWFBSOgogICAgc2hpZnQ6CiAgICAgIGlmIChpbnRlZ2VyX3plcm9wIChhcmcxKSkKCXJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzApKTsKICAgICAgaWYgKGludGVnZXJfemVyb3AgKGFyZzApKQoJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIGFyZzAsIGFyZzEpOwoKICAgICAgLyogU2luY2UgbmVnYXRpdmUgc2hpZnQgY291bnQgaXMgbm90IHdlbGwtZGVmaW5lZCwKCSBkb24ndCB0cnkgdG8gY29tcHV0ZSBpdCBpbiB0aGUgY29tcGlsZXIuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBJTlRFR0VSX0NTVCAmJiB0cmVlX2ludF9jc3Rfc2duIChhcmcxKSA8IDApCglyZXR1cm4gdDsKICAgICAgLyogUmV3cml0ZSBhbiBMUk9UQVRFX0VYUFIgYnkgYSBjb25zdGFudCBpbnRvIGFuCgkgUlJPVEFURV9FWFBSIGJ5IGEgbmV3IGNvbnN0YW50LiAgKi8KICAgICAgaWYgKGNvZGUgPT0gTFJPVEFURV9FWFBSICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QpCgl7CgkgIHRyZWUgdGVtID0gYnVpbGRfaW50XzIgKEdFVF9NT0RFX0JJVFNJWkUgKFRZUEVfTU9ERSAodHlwZSkpLCAwKTsKCSAgdGVtID0gZm9sZF9jb252ZXJ0IChUUkVFX1RZUEUgKGFyZzEpLCB0ZW0pOwoJICB0ZW0gPSBjb25zdF9iaW5vcCAoTUlOVVNfRVhQUiwgdGVtLCBhcmcxLCAwKTsKCSAgcmV0dXJuIGZvbGQgKGJ1aWxkIChSUk9UQVRFX0VYUFIsIHR5cGUsIGFyZzAsIHRlbSkpOwoJfQoKICAgICAgLyogSWYgd2UgaGF2ZSBhIHJvdGF0ZSBvZiBhIGJpdCBvcGVyYXRpb24gd2l0aCB0aGUgcm90YXRlIGNvdW50IGFuZAoJIHRoZSBzZWNvbmQgb3BlcmFuZCBvZiB0aGUgYml0IG9wZXJhdGlvbiBib3RoIGNvbnN0YW50LAoJIHBlcm11dGUgdGhlIHR3byBvcGVyYXRpb25zLiAgKi8KICAgICAgaWYgKGNvZGUgPT0gUlJPVEFURV9FWFBSICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QKCSAgJiYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQklUX0FORF9FWFBSCgkgICAgICB8fCBUUkVFX0NPREUgKGFyZzApID09IEJJVF9JT1JfRVhQUgoJICAgICAgfHwgVFJFRV9DT0RFIChhcmcwKSA9PSBCSVRfWE9SX0VYUFIpCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkgPT0gSU5URUdFUl9DU1QpCglyZXR1cm4gZm9sZCAoYnVpbGQgKFRSRUVfQ09ERSAoYXJnMCksIHR5cGUsCgkJCSAgICBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwKCQkJCQkgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgYXJnMSkpLAoJCQkgICAgZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsCgkJCQkJIFRSRUVfT1BFUkFORCAoYXJnMCwgMSksIGFyZzEpKSkpOwoKICAgICAgLyogVHdvIGNvbnNlY3V0aXZlIHJvdGF0ZXMgYWRkaW5nIHVwIHRvIHRoZSB3aWR0aCBvZiB0aGUgbW9kZSBjYW4KCSBiZSBpZ25vcmVkLiAgKi8KICAgICAgaWYgKGNvZGUgPT0gUlJPVEFURV9FWFBSICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QKCSAgJiYgVFJFRV9DT0RFIChhcmcwKSA9PSBSUk9UQVRFX0VYUFIKCSAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSA9PSBJTlRFR0VSX0NTVAoJICAmJiBUUkVFX0lOVF9DU1RfSElHSCAoYXJnMSkgPT0gMAoJICAmJiBUUkVFX0lOVF9DU1RfSElHSCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkgPT0gMAoJICAmJiAoKFRSRUVfSU5UX0NTVF9MT1cgKGFyZzEpCgkgICAgICAgKyBUUkVFX0lOVF9DU1RfTE9XIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSkKCSAgICAgID09ICh1bnNpZ25lZCBpbnQpIEdFVF9NT0RFX0JJVFNJWkUgKFRZUEVfTU9ERSAodHlwZSkpKSkKCXJldHVybiBUUkVFX09QRVJBTkQgKGFyZzAsIDApOwoKICAgICAgZ290byBiaW5hcnk7CgogICAgY2FzZSBNSU5fRVhQUjoKICAgICAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoYXJnMCwgYXJnMSwgMCkpCglyZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgYXJnMCwgYXJnMSk7CiAgICAgIGlmIChJTlRFR1JBTF9UWVBFX1AgKHR5cGUpCgkgICYmIG9wZXJhbmRfZXF1YWxfcCAoYXJnMSwgVFlQRV9NSU5fVkFMVUUgKHR5cGUpLCAxKSkKCXJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLCBhcmcxLCBhcmcwKTsKICAgICAgZ290byBhc3NvY2lhdGU7CgogICAgY2FzZSBNQVhfRVhQUjoKICAgICAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoYXJnMCwgYXJnMSwgMCkpCglyZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgYXJnMCwgYXJnMSk7CiAgICAgIGlmIChJTlRFR1JBTF9UWVBFX1AgKHR5cGUpCgkgICYmIFRZUEVfTUFYX1ZBTFVFICh0eXBlKQoJICAmJiBvcGVyYW5kX2VxdWFsX3AgKGFyZzEsIFRZUEVfTUFYX1ZBTFVFICh0eXBlKSwgMSkpCglyZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgYXJnMSwgYXJnMCk7CiAgICAgIGdvdG8gYXNzb2NpYXRlOwoKICAgIGNhc2UgVFJVVEhfTk9UX0VYUFI6CiAgICAgIC8qIE5vdGUgdGhhdCB0aGUgb3BlcmFuZCBvZiB0aGlzIG11c3QgYmUgYW4gaW50CgkgYW5kIGl0cyB2YWx1ZXMgbXVzdCBiZSAwIG9yIDEuCgkgKCJ0cnVlIiBpcyBhIGZpeGVkIHZhbHVlIHBlcmhhcHMgZGVwZW5kaW5nIG9uIHRoZSBsYW5ndWFnZSwKCSBidXQgd2UgZG9uJ3QgaGFuZGxlIHZhbHVlcyBvdGhlciB0aGFuIDEgY29ycmVjdGx5IHlldC4pICAqLwogICAgICB0ZW0gPSBpbnZlcnRfdHJ1dGh2YWx1ZSAoYXJnMCk7CiAgICAgIC8qIEF2b2lkIGluZmluaXRlIHJlY3Vyc2lvbi4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKHRlbSkgPT0gVFJVVEhfTk9UX0VYUFIpCgl7CgkgIHRlbSA9IGZvbGRfc2luZ2xlX2JpdF90ZXN0IChjb2RlLCBhcmcwLCBhcmcxLCB0eXBlKTsKCSAgaWYgKHRlbSkKCSAgICByZXR1cm4gdGVtOwoJICByZXR1cm4gdDsKCX0KICAgICAgcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgdGVtKTsKCiAgICBjYXNlIFRSVVRIX0FORElGX0VYUFI6CiAgICAgIC8qIE5vdGUgdGhhdCB0aGUgb3BlcmFuZHMgb2YgdGhpcyBtdXN0IGJlIGludHMKCSBhbmQgdGhlaXIgdmFsdWVzIG11c3QgYmUgMCBvciAxLgoJICgidHJ1ZSIgaXMgYSBmaXhlZCB2YWx1ZSBwZXJoYXBzIGRlcGVuZGluZyBvbiB0aGUgbGFuZ3VhZ2UuKSAgKi8KICAgICAgLyogSWYgZmlyc3QgYXJnIGlzIGNvbnN0YW50IHplcm8sIHJldHVybiBpdC4gICovCiAgICAgIGlmIChpbnRlZ2VyX3plcm9wIChhcmcwKSkKCXJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzApOwogICAgY2FzZSBUUlVUSF9BTkRfRVhQUjoKICAgICAgLyogSWYgZWl0aGVyIGFyZyBpcyBjb25zdGFudCB0cnVlLCBkcm9wIGl0LiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gSU5URUdFUl9DU1QgJiYgISBpbnRlZ2VyX3plcm9wIChhcmcwKSkKCXJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzEpKTsKICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QgJiYgISBpbnRlZ2VyX3plcm9wIChhcmcxKQoJICAvKiBQcmVzZXJ2ZSBzZXF1ZW5jZSBwb2ludHMuICAqLwoJICAmJiAoY29kZSAhPSBUUlVUSF9BTkRJRl9FWFBSIHx8ICEgVFJFRV9TSURFX0VGRkVDVFMgKGFyZzApKSkKCXJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzApKTsKICAgICAgLyogSWYgc2Vjb25kIGFyZyBpcyBjb25zdGFudCB6ZXJvLCByZXN1bHQgaXMgemVybywgYnV0IGZpcnN0IGFyZwoJIG11c3QgYmUgZXZhbHVhdGVkLiAgKi8KICAgICAgaWYgKGludGVnZXJfemVyb3AgKGFyZzEpKQoJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIGFyZzEsIGFyZzApOwogICAgICAvKiBMaWtld2lzZSBmb3IgZmlyc3QgYXJnLCBidXQgbm90ZSB0aGF0IG9ubHkgdGhlIFRSVVRIX0FORF9FWFBSCgkgY2FzZSB3aWxsIGJlIGhhbmRsZWQgaGVyZS4gICovCiAgICAgIGlmIChpbnRlZ2VyX3plcm9wIChhcmcwKSkKCXJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLCBhcmcwLCBhcmcxKTsKCiAgICB0cnV0aF9hbmRvcjoKICAgICAgLyogV2Ugb25seSBkbyB0aGVzZSBzaW1wbGlmaWNhdGlvbnMgaWYgd2UgYXJlIG9wdGltaXppbmcuICAqLwogICAgICBpZiAoIW9wdGltaXplKQoJcmV0dXJuIHQ7CgogICAgICAvKiBDaGVjayBmb3IgdGhpbmdzIGxpa2UgKEEgfHwgQikgJiYgKEEgfHwgQykuICBXZSBjYW4gY29udmVydCB0aGlzCgkgdG8gQSB8fCAoQiAmJiBDKS4gIE5vdGUgdGhhdCBlaXRoZXIgb3BlcmF0b3IgY2FuIGJlIGFueSBvZiB0aGUgZm91cgoJIHRydXRoIGFuZC9vciBvcGVyYXRpb25zIGFuZCB0aGUgdHJhbnNmb3JtYXRpb24gd2lsbCBzdGlsbCBiZQoJIHZhbGlkLiAgIEFsc28gbm90ZSB0aGF0IHdlIG9ubHkgY2FyZSBhYm91dCBvcmRlciBmb3IgdGhlCgkgQU5ESUYgYW5kIE9SSUYgb3BlcmF0b3JzLiAgSWYgQiBjb250YWlucyBzaWRlIGVmZmVjdHMsIHRoaXMKCSBtaWdodCBjaGFuZ2UgdGhlIHRydXRoLXZhbHVlIG9mIEEuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBUUkVFX0NPREUgKGFyZzEpCgkgICYmIChUUkVFX0NPREUgKGFyZzApID09IFRSVVRIX0FORElGX0VYUFIKCSAgICAgIHx8IFRSRUVfQ09ERSAoYXJnMCkgPT0gVFJVVEhfT1JJRl9FWFBSCgkgICAgICB8fCBUUkVFX0NPREUgKGFyZzApID09IFRSVVRIX0FORF9FWFBSCgkgICAgICB8fCBUUkVFX0NPREUgKGFyZzApID09IFRSVVRIX09SX0VYUFIpCgkgICYmICEgVFJFRV9TSURFX0VGRkVDVFMgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpKQoJewoJICB0cmVlIGEwMCA9IFRSRUVfT1BFUkFORCAoYXJnMCwgMCk7CgkgIHRyZWUgYTAxID0gVFJFRV9PUEVSQU5EIChhcmcwLCAxKTsKCSAgdHJlZSBhMTAgPSBUUkVFX09QRVJBTkQgKGFyZzEsIDApOwoJICB0cmVlIGExMSA9IFRSRUVfT1BFUkFORCAoYXJnMSwgMSk7CgkgIGludCBjb21tdXRhdGl2ZSA9ICgoVFJFRV9DT0RFIChhcmcwKSA9PSBUUlVUSF9PUl9FWFBSCgkJCSAgICAgIHx8IFRSRUVfQ09ERSAoYXJnMCkgPT0gVFJVVEhfQU5EX0VYUFIpCgkJCSAgICAgJiYgKGNvZGUgPT0gVFJVVEhfQU5EX0VYUFIKCQkJCSB8fCBjb2RlID09IFRSVVRIX09SX0VYUFIpKTsKCgkgIGlmIChvcGVyYW5kX2VxdWFsX3AgKGEwMCwgYTEwLCAwKSkKCSAgICByZXR1cm4gZm9sZCAoYnVpbGQgKFRSRUVfQ09ERSAoYXJnMCksIHR5cGUsIGEwMCwKCQkJCWZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLCBhMDEsIGExMSkpKSk7CgkgIGVsc2UgaWYgKGNvbW11dGF0aXZlICYmIG9wZXJhbmRfZXF1YWxfcCAoYTAwLCBhMTEsIDApKQoJICAgIHJldHVybiBmb2xkIChidWlsZCAoVFJFRV9DT0RFIChhcmcwKSwgdHlwZSwgYTAwLAoJCQkJZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIGEwMSwgYTEwKSkpKTsKCSAgZWxzZSBpZiAoY29tbXV0YXRpdmUgJiYgb3BlcmFuZF9lcXVhbF9wIChhMDEsIGExMCwgMCkpCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChUUkVFX0NPREUgKGFyZzApLCB0eXBlLCBhMDEsCgkJCQlmb2xkIChidWlsZCAoY29kZSwgdHlwZSwgYTAwLCBhMTEpKSkpOwoKCSAgLyogVGhpcyBjYXNlIGlmIHRyaWNreSBiZWNhdXNlIHdlIG11c3QgZWl0aGVyIGhhdmUgY29tbXV0YXRpdmUKCSAgICAgb3BlcmF0b3JzIG9yIGVsc2UgQTEwIG11c3Qgbm90IGhhdmUgc2lkZS1lZmZlY3RzLiAgKi8KCgkgIGVsc2UgaWYgKChjb21tdXRhdGl2ZSB8fCAhIFRSRUVfU0lERV9FRkZFQ1RTIChhMTApKQoJCSAgICYmIG9wZXJhbmRfZXF1YWxfcCAoYTAxLCBhMTEsIDApKQoJICAgIHJldHVybiBmb2xkIChidWlsZCAoVFJFRV9DT0RFIChhcmcwKSwgdHlwZSwKCQkJCWZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLCBhMDAsIGExMCkpLAoJCQkJYTAxKSk7Cgl9CgogICAgICAvKiBTZWUgaWYgd2UgY2FuIGJ1aWxkIGEgcmFuZ2UgY29tcGFyaXNvbi4gICovCiAgICAgIGlmICgwICE9ICh0ZW0gPSBmb2xkX3JhbmdlX3Rlc3QgKHQpKSkKCXJldHVybiB0ZW07CgogICAgICAvKiBDaGVjayBmb3IgdGhlIHBvc3NpYmlsaXR5IG9mIG1lcmdpbmcgY29tcG9uZW50IHJlZmVyZW5jZXMuICBJZiBvdXIKCSBsaHMgaXMgYW5vdGhlciBzaW1pbGFyIG9wZXJhdGlvbiwgdHJ5IHRvIG1lcmdlIGl0cyByaHMgd2l0aCBvdXIKCSByaHMuICBUaGVuIHRyeSB0byBtZXJnZSBvdXIgbGhzIGFuZCByaHMuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBjb2RlCgkgICYmIDAgIT0gKHRlbSA9IGZvbGRfdHJ1dGhvcCAoY29kZSwgdHlwZSwKCQkJCSAgICAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDEpLCBhcmcxKSkpCglyZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksIHRlbSkpOwoKICAgICAgaWYgKCh0ZW0gPSBmb2xkX3RydXRob3AgKGNvZGUsIHR5cGUsIGFyZzAsIGFyZzEpKSAhPSAwKQoJcmV0dXJuIHRlbTsKCiAgICAgIHJldHVybiB0OwoKICAgIGNhc2UgVFJVVEhfT1JJRl9FWFBSOgogICAgICAvKiBOb3RlIHRoYXQgdGhlIG9wZXJhbmRzIG9mIHRoaXMgbXVzdCBiZSBpbnRzCgkgYW5kIHRoZWlyIHZhbHVlcyBtdXN0IGJlIDAgb3IgdHJ1ZS4KCSAoInRydWUiIGlzIGEgZml4ZWQgdmFsdWUgcGVyaGFwcyBkZXBlbmRpbmcgb24gdGhlIGxhbmd1YWdlLikgICovCiAgICAgIC8qIElmIGZpcnN0IGFyZyBpcyBjb25zdGFudCB0cnVlLCByZXR1cm4gaXQuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBJTlRFR0VSX0NTVCAmJiAhIGludGVnZXJfemVyb3AgKGFyZzApKQoJcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgYXJnMCk7CiAgICBjYXNlIFRSVVRIX09SX0VYUFI6CiAgICAgIC8qIElmIGVpdGhlciBhcmcgaXMgY29uc3RhbnQgemVybywgZHJvcCBpdC4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzApID09IElOVEVHRVJfQ1NUICYmIGludGVnZXJfemVyb3AgKGFyZzApKQoJcmV0dXJuIG5vbl9sdmFsdWUgKGZvbGRfY29udmVydCAodHlwZSwgYXJnMSkpOwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBJTlRFR0VSX0NTVCAmJiBpbnRlZ2VyX3plcm9wIChhcmcxKQoJICAvKiBQcmVzZXJ2ZSBzZXF1ZW5jZSBwb2ludHMuICAqLwoJICAmJiAoY29kZSAhPSBUUlVUSF9PUklGX0VYUFIgfHwgISBUUkVFX1NJREVfRUZGRUNUUyAoYXJnMCkpKQoJcmV0dXJuIG5vbl9sdmFsdWUgKGZvbGRfY29udmVydCAodHlwZSwgYXJnMCkpOwogICAgICAvKiBJZiBzZWNvbmQgYXJnIGlzIGNvbnN0YW50IHRydWUsIHJlc3VsdCBpcyB0cnVlLCBidXQgd2UgbXVzdAoJIGV2YWx1YXRlIGZpcnN0IGFyZy4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUICYmICEgaW50ZWdlcl96ZXJvcCAoYXJnMSkpCglyZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgYXJnMSwgYXJnMCk7CiAgICAgIC8qIExpa2V3aXNlIGZvciBmaXJzdCBhcmcsIGJ1dCBub3RlIHRoaXMgb25seSBvY2N1cnMgaGVyZSBmb3IKCSBUUlVUSF9PUl9FWFBSLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gSU5URUdFUl9DU1QgJiYgISBpbnRlZ2VyX3plcm9wIChhcmcwKSkKCXJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLCBhcmcwLCBhcmcxKTsKICAgICAgZ290byB0cnV0aF9hbmRvcjsKCiAgICBjYXNlIFRSVVRIX1hPUl9FWFBSOgogICAgICAvKiBJZiBlaXRoZXIgYXJnIGlzIGNvbnN0YW50IHplcm8sIGRyb3AgaXQuICAqLwogICAgICBpZiAoaW50ZWdlcl96ZXJvcCAoYXJnMCkpCglyZXR1cm4gbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcxKSk7CiAgICAgIGlmIChpbnRlZ2VyX3plcm9wIChhcmcxKSkKCXJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzApKTsKICAgICAgLyogSWYgZWl0aGVyIGFyZyBpcyBjb25zdGFudCB0cnVlLCB0aGlzIGlzIGEgbG9naWNhbCBpbnZlcnNpb24uICAqLwogICAgICBpZiAoaW50ZWdlcl9vbmVwIChhcmcwKSkKCXJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGludmVydF90cnV0aHZhbHVlIChhcmcxKSkpOwogICAgICBpZiAoaW50ZWdlcl9vbmVwIChhcmcxKSkKCXJldHVybiBub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGludmVydF90cnV0aHZhbHVlIChhcmcwKSkpOwogICAgICByZXR1cm4gdDsKCiAgICBjYXNlIEVRX0VYUFI6CiAgICBjYXNlIE5FX0VYUFI6CiAgICBjYXNlIExUX0VYUFI6CiAgICBjYXNlIEdUX0VYUFI6CiAgICBjYXNlIExFX0VYUFI6CiAgICBjYXNlIEdFX0VYUFI6CiAgICAgIC8qIElmIG9uZSBhcmcgaXMgYSByZWFsIG9yIGludGVnZXIgY29uc3RhbnQsIHB1dCBpdCBsYXN0LiAgKi8KICAgICAgaWYgKHRyZWVfc3dhcF9vcGVyYW5kc19wIChhcmcwLCBhcmcxLCB0cnVlKSkKCXJldHVybiBmb2xkIChidWlsZCAoc3dhcF90cmVlX2NvbXBhcmlzb24gKGNvZGUpLCB0eXBlLCBhcmcxLCBhcmcwKSk7CgogICAgICBpZiAoRkxPQVRfVFlQRV9QIChUUkVFX1RZUEUgKGFyZzApKSkKCXsKCSAgdHJlZSB0YXJnMCA9IHN0cmlwX2Zsb2F0X2V4dGVuc2lvbnMgKGFyZzApOwoJICB0cmVlIHRhcmcxID0gc3RyaXBfZmxvYXRfZXh0ZW5zaW9ucyAoYXJnMSk7CgkgIHRyZWUgbmV3dHlwZSA9IFRSRUVfVFlQRSAodGFyZzApOwoKCSAgaWYgKFRZUEVfUFJFQ0lTSU9OIChUUkVFX1RZUEUgKHRhcmcxKSkgPiBUWVBFX1BSRUNJU0lPTiAobmV3dHlwZSkpCgkgICAgbmV3dHlwZSA9IFRSRUVfVFlQRSAodGFyZzEpOwoKCSAgLyogRm9sZCAoZG91YmxlKWZsb2F0MSBDTVAgKGRvdWJsZSlmbG9hdDIgaW50byBmbG9hdDEgQ01QIGZsb2F0Mi4gICovCgkgIGlmIChUWVBFX1BSRUNJU0lPTiAobmV3dHlwZSkgPCBUWVBFX1BSRUNJU0lPTiAoVFJFRV9UWVBFIChhcmcwKSkpCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLCBmb2xkX2NvbnZlcnQgKG5ld3R5cGUsIHRhcmcwKSwKCQkJCWZvbGRfY29udmVydCAobmV3dHlwZSwgdGFyZzEpKSk7CgoJICAvKiAoLWEpIENNUCAoLWIpIC0+IGIgQ01QIGEgICovCgkgIGlmIChUUkVFX0NPREUgKGFyZzApID09IE5FR0FURV9FWFBSCgkgICAgICAmJiBUUkVFX0NPREUgKGFyZzEpID09IE5FR0FURV9FWFBSKQoJICAgIHJldHVybiBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwgVFJFRV9PUEVSQU5EIChhcmcxLCAwKSwKCQkJCVRSRUVfT1BFUkFORCAoYXJnMCwgMCkpKTsKCgkgIGlmIChUUkVFX0NPREUgKGFyZzEpID09IFJFQUxfQ1NUKQoJICB7CgkgICAgUkVBTF9WQUxVRV9UWVBFIGNzdDsKCSAgICBjc3QgPSBUUkVFX1JFQUxfQ1NUIChhcmcxKTsKCgkgICAgLyogKC1hKSBDTVAgQ1NUIC0+IGEgc3dhcChDTVApICgtQ1NUKSAgKi8KCSAgICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBORUdBVEVfRVhQUikKCSAgICAgIHJldHVybgoJCWZvbGQgKGJ1aWxkIChzd2FwX3RyZWVfY29tcGFyaXNvbiAoY29kZSksIHR5cGUsCgkJCSAgICAgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwKCQkJICAgICBidWlsZF9yZWFsIChUUkVFX1RZUEUgKGFyZzEpLAoJCQkJCSBSRUFMX1ZBTFVFX05FR0FURSAoY3N0KSkpKTsKCgkgICAgLyogSUVFRSBkb2Vzbid0IGRpc3Rpbmd1aXNoICswIGFuZCAtMCBpbiBjb21wYXJpc29ucy4gICovCgkgICAgLyogYSBDTVAgKC0wKSAtPiBhIENNUCAwICAqLwoJICAgIGlmIChSRUFMX1ZBTFVFX01JTlVTX1pFUk8gKGNzdCkpCgkgICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIGFyZzAsCgkJCQkgIGJ1aWxkX3JlYWwgKFRSRUVfVFlQRSAoYXJnMSksIGRjb25zdDApKSk7CgoJICAgIC8qIHggIT0gTmFOIGlzIGFsd2F5cyB0cnVlLCBvdGhlciBvcHMgYXJlIGFsd2F5cyBmYWxzZS4gICovCgkgICAgaWYgKFJFQUxfVkFMVUVfSVNOQU4gKGNzdCkKCQkmJiAhIEhPTk9SX1NOQU5TIChUWVBFX01PREUgKFRSRUVfVFlQRSAoYXJnMSkpKSkKCSAgICAgIHsKCQl0ID0gKGNvZGUgPT0gTkVfRVhQUikgPyBpbnRlZ2VyX29uZV9ub2RlIDogaW50ZWdlcl96ZXJvX25vZGU7CgkJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIGZvbGRfY29udmVydCAodHlwZSwgdCksIGFyZzApOwoJICAgICAgfQoKCSAgICAvKiBGb2xkIGNvbXBhcmlzb25zIGFnYWluc3QgaW5maW5pdHkuICAqLwoJICAgIGlmIChSRUFMX1ZBTFVFX0lTSU5GIChjc3QpKQoJICAgICAgewoJCXRlbSA9IGZvbGRfaW5mX2NvbXBhcmUgKGNvZGUsIHR5cGUsIGFyZzAsIGFyZzEpOwoJCWlmICh0ZW0gIT0gTlVMTF9UUkVFKQoJCSAgcmV0dXJuIHRlbTsKCSAgICAgIH0KCSAgfQoKCSAgLyogSWYgdGhpcyBpcyBhIGNvbXBhcmlzb24gb2YgYSByZWFsIGNvbnN0YW50IHdpdGggYSBQTFVTX0VYUFIKCSAgICAgb3IgYSBNSU5VU19FWFBSIG9mIGEgcmVhbCBjb25zdGFudCwgd2UgY2FuIGNvbnZlcnQgaXQgaW50byBhCgkgICAgIGNvbXBhcmlzb24gd2l0aCBhIHJldmlzZWQgcmVhbCBjb25zdGFudCBhcyBsb25nIGFzIG5vIG92ZXJmbG93CgkgICAgIG9jY3VycyB3aGVuIHVuc2FmZV9tYXRoX29wdGltaXphdGlvbnMgYXJlIGVuYWJsZWQuICAqLwoJICBpZiAoZmxhZ191bnNhZmVfbWF0aF9vcHRpbWl6YXRpb25zCgkgICAgICAmJiBUUkVFX0NPREUgKGFyZzEpID09IFJFQUxfQ1NUCgkgICAgICAmJiAoVFJFRV9DT0RFIChhcmcwKSA9PSBQTFVTX0VYUFIKCQkgIHx8IFRSRUVfQ09ERSAoYXJnMCkgPT0gTUlOVVNfRVhQUikKCSAgICAgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkgPT0gUkVBTF9DU1QKCSAgICAgICYmIDAgIT0gKHRlbSA9IGNvbnN0X2Jpbm9wIChUUkVFX0NPREUgKGFyZzApID09IFBMVVNfRVhQUgoJCQkJCSAgPyBNSU5VU19FWFBSIDogUExVU19FWFBSLAoJCQkJCSAgYXJnMSwgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwgMCkpCgkgICAgICAmJiAhIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKHRlbSkpCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLCBUUkVFX09QRVJBTkQgKGFyZzAsIDApLCB0ZW0pKTsKCgkgIC8qIExpa2V3aXNlLCB3ZSBjYW4gc2ltcGxpZnkgYSBjb21wYXJpc29uIG9mIGEgcmVhbCBjb25zdGFudCB3aXRoCgkgICAgIGEgTUlOVVNfRVhQUiB3aG9zZSBmaXJzdCBvcGVyYW5kIGlzIGFsc28gYSByZWFsIGNvbnN0YW50LCBpLmUuCgkgICAgIChjMSAtIHgpIDwgYzIgYmVjb21lcyB4ID4gYzEtYzIuICAqLwoJICBpZiAoZmxhZ191bnNhZmVfbWF0aF9vcHRpbWl6YXRpb25zCgkgICAgICAmJiBUUkVFX0NPREUgKGFyZzEpID09IFJFQUxfQ1NUCgkgICAgICAmJiBUUkVFX0NPREUgKGFyZzApID09IE1JTlVTX0VYUFIKCSAgICAgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSkgPT0gUkVBTF9DU1QKCSAgICAgICYmIDAgIT0gKHRlbSA9IGNvbnN0X2Jpbm9wIChNSU5VU19FWFBSLCBUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkJCSAgYXJnMSwgMCkpCgkgICAgICAmJiAhIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKHRlbSkpCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChzd2FwX3RyZWVfY29tcGFyaXNvbiAoY29kZSksIHR5cGUsCgkJCQlUUkVFX09QRVJBTkQgKGFyZzAsIDEpLCB0ZW0pKTsKCgkgIC8qIEZvbGQgY29tcGFyaXNvbnMgYWdhaW5zdCBidWlsdC1pbiBtYXRoIGZ1bmN0aW9ucy4gICovCgkgIGlmIChUUkVFX0NPREUgKGFyZzEpID09IFJFQUxfQ1NUCgkgICAgICAmJiBmbGFnX3Vuc2FmZV9tYXRoX29wdGltaXphdGlvbnMKCSAgICAgICYmICEgZmxhZ19lcnJub19tYXRoKQoJICAgIHsKCSAgICAgIGVudW0gYnVpbHRfaW5fZnVuY3Rpb24gZmNvZGUgPSBidWlsdGluX21hdGhmbl9jb2RlIChhcmcwKTsKCgkgICAgICBpZiAoZmNvZGUgIT0gRU5EX0JVSUxUSU5TKQoJCXsKCQkgIHRlbSA9IGZvbGRfbWF0aGZuX2NvbXBhcmUgKGZjb2RlLCBjb2RlLCB0eXBlLCBhcmcwLCBhcmcxKTsKCQkgIGlmICh0ZW0gIT0gTlVMTF9UUkVFKQoJCSAgICByZXR1cm4gdGVtOwoJCX0KCSAgICB9Cgl9CgogICAgICAvKiBDb252ZXJ0IGZvbysrID09IENPTlNUIGludG8gKytmb28gPT0gQ09OU1QgKyBJTkNSLiAgKi8KICAgICAgaWYgKFRSRUVfQ09OU1RBTlQgKGFyZzEpCgkgICYmIChUUkVFX0NPREUgKGFyZzApID09IFBPU1RJTkNSRU1FTlRfRVhQUgoJICAgICAgfHwgVFJFRV9DT0RFIChhcmcwKSA9PSBQT1NUREVDUkVNRU5UX0VYUFIpCgkgIC8qIFRoaXMgb3B0aW1pemF0aW9uIGlzIGludmFsaWQgZm9yIG9yZGVyZWQgY29tcGFyaXNvbnMKCSAgICAgaWYgQ09OU1QrSU5DUiBvdmVyZmxvd3Mgb3IgaWYgZm9vK2luY3IgbWlnaHQgb3ZlcmZsb3cuCgkgICAgIFRoaXMgb3B0aW1pemF0aW9uIGlzIGludmFsaWQgZm9yIGZsb2F0aW5nIHBvaW50IGR1ZSB0byByb3VuZGluZy4KCSAgICAgRm9yIHBvaW50ZXIgdHlwZXMgd2UgYXNzdW1lIG92ZXJmbG93IGRvZXNuJ3QgaGFwcGVuLiAgKi8KCSAgJiYgKFBPSU5URVJfVFlQRV9QIChUUkVFX1RZUEUgKGFyZzApKQoJICAgICAgfHwgKElOVEVHUkFMX1RZUEVfUCAoVFJFRV9UWVBFIChhcmcwKSkKCQkgICYmIChjb2RlID09IEVRX0VYUFIgfHwgY29kZSA9PSBORV9FWFBSKSkpKQoJewoJICB0cmVlIHZhcm9wLCBuZXdjb25zdDsKCgkgIGlmIChUUkVFX0NPREUgKGFyZzApID09IFBPU1RJTkNSRU1FTlRfRVhQUikKCSAgICB7CgkgICAgICBuZXdjb25zdCA9IGZvbGQgKGJ1aWxkIChQTFVTX0VYUFIsIFRSRUVfVFlQRSAoYXJnMCksCgkJCQkgICAgICBhcmcxLCBUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSk7CgkgICAgICB2YXJvcCA9IGJ1aWxkIChQUkVJTkNSRU1FTlRfRVhQUiwgVFJFRV9UWVBFIChhcmcwKSwKCQkJICAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkgICAgIFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpOwoJICAgIH0KCSAgZWxzZQoJICAgIHsKCSAgICAgIG5ld2NvbnN0ID0gZm9sZCAoYnVpbGQgKE1JTlVTX0VYUFIsIFRSRUVfVFlQRSAoYXJnMCksCgkJCQkgICAgICBhcmcxLCBUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSk7CgkgICAgICB2YXJvcCA9IGJ1aWxkIChQUkVERUNSRU1FTlRfRVhQUiwgVFJFRV9UWVBFIChhcmcwKSwKCQkJICAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDApLAoJCQkgICAgIFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpOwoJICAgIH0KCgoJICAvKiBJZiBWQVJPUCBpcyBhIHJlZmVyZW5jZSB0byBhIGJpdGZpZWxkLCB3ZSBtdXN0IG1hc2sKCSAgICAgdGhlIGNvbnN0YW50IGJ5IHRoZSB3aWR0aCBvZiB0aGUgZmllbGQuICAqLwoJICBpZiAoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHZhcm9wLCAwKSkgPT0gQ09NUE9ORU5UX1JFRgoJICAgICAgJiYgREVDTF9CSVRfRklFTEQgKFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh2YXJvcCwgMCksIDEpKSkKCSAgICB7CgkgICAgICB0cmVlIGZpZWxkZGVjbCA9IFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh2YXJvcCwgMCksIDEpOwoJICAgICAgaW50IHNpemUgPSBUUkVFX0lOVF9DU1RfTE9XIChERUNMX1NJWkUgKGZpZWxkZGVjbCkpOwoJICAgICAgdHJlZSBmb2xkZWRfY29tcGFyZSwgc2hpZnQ7CgoJICAgICAgLyogRmlyc3QgY2hlY2sgd2hldGhlciB0aGUgY29tcGFyaXNvbiB3b3VsZCBjb21lIG91dAoJCSBhbHdheXMgdGhlIHNhbWUuICBJZiB3ZSBkb24ndCBkbyB0aGF0IHdlIHdvdWxkCgkJIGNoYW5nZSB0aGUgbWVhbmluZyB3aXRoIHRoZSBtYXNraW5nLiAgKi8KCSAgICAgIGZvbGRlZF9jb21wYXJlID0gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsCgkJCQkJICAgIFRSRUVfT1BFUkFORCAodmFyb3AsIDApLAoJCQkJCSAgICBhcmcxKSk7CgkgICAgICBpZiAoaW50ZWdlcl96ZXJvcCAoZm9sZGVkX2NvbXBhcmUpCgkJICB8fCBpbnRlZ2VyX29uZXAgKGZvbGRlZF9jb21wYXJlKSkKCQlyZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgZm9sZGVkX2NvbXBhcmUsIHZhcm9wKTsKCgkgICAgICBzaGlmdCA9IGJ1aWxkX2ludF8yIChUWVBFX1BSRUNJU0lPTiAoVFJFRV9UWVBFICh2YXJvcCkpIC0gc2l6ZSwKCQkJCSAgIDApOwoJICAgICAgbmV3Y29uc3QgPSBmb2xkIChidWlsZCAoTFNISUZUX0VYUFIsIFRSRUVfVFlQRSAodmFyb3ApLAoJCQkJICAgICAgbmV3Y29uc3QsIHNoaWZ0KSk7CgkgICAgICBuZXdjb25zdCA9IGZvbGQgKGJ1aWxkIChSU0hJRlRfRVhQUiwgVFJFRV9UWVBFICh2YXJvcCksCgkJCQkgICAgICBuZXdjb25zdCwgc2hpZnQpKTsKCSAgICB9CgoJICByZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIHZhcm9wLCBuZXdjb25zdCkpOwoJfQoKICAgICAgLyogQ2hhbmdlIFggPj0gQyB0byBYID4gKEMgLSAxKSBhbmQgWCA8IEMgdG8gWCA8PSAoQyAtIDEpIGlmIEMgPiAwLgoJIFRoaXMgdHJhbnNmb3JtYXRpb24gYWZmZWN0cyB0aGUgY2FzZXMgd2hpY2ggYXJlIGhhbmRsZWQgaW4gbGF0ZXIKCSBvcHRpbWl6YXRpb25zIGludm9sdmluZyBjb21wYXJpc29ucyB3aXRoIG5vbi1uZWdhdGl2ZSBjb25zdGFudHMuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBJTlRFR0VSX0NTVAoJICAmJiBUUkVFX0NPREUgKGFyZzApICE9IElOVEVHRVJfQ1NUCgkgICYmIHRyZWVfaW50X2NzdF9zZ24gKGFyZzEpID4gMCkKCXsKCSAgc3dpdGNoIChjb2RlKQoJICAgIHsKCSAgICBjYXNlIEdFX0VYUFI6CgkgICAgICBhcmcxID0gY29uc3RfYmlub3AgKE1JTlVTX0VYUFIsIGFyZzEsIGludGVnZXJfb25lX25vZGUsIDApOwoJICAgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChHVF9FWFBSLCB0eXBlLCBhcmcwLCBhcmcxKSk7CgoJICAgIGNhc2UgTFRfRVhQUjoKCSAgICAgIGFyZzEgPSBjb25zdF9iaW5vcCAoTUlOVVNfRVhQUiwgYXJnMSwgaW50ZWdlcl9vbmVfbm9kZSwgMCk7CgkgICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKExFX0VYUFIsIHR5cGUsIGFyZzAsIGFyZzEpKTsKCgkgICAgZGVmYXVsdDoKCSAgICAgIGJyZWFrOwoJICAgIH0KCX0KCiAgICAgIC8qIENvbXBhcmlzb25zIHdpdGggdGhlIGhpZ2hlc3Qgb3IgbG93ZXN0IHBvc3NpYmxlIGludGVnZXIgb2YKCSB0aGUgc3BlY2lmaWVkIHNpemUgd2lsbCBoYXZlIGtub3duIHZhbHVlcy4gICovCiAgICAgIHsKCWludCB3aWR0aCA9IEdFVF9NT0RFX0JJVFNJWkUgKFRZUEVfTU9ERSAoVFJFRV9UWVBFIChhcmcxKSkpOwoKCWlmIChUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUCgkgICAgJiYgISBUUkVFX0NPTlNUQU5UX09WRVJGTE9XIChhcmcxKQoJICAgICYmIHdpZHRoIDw9IEhPU1RfQklUU19QRVJfV0lERV9JTlQKCSAgICAmJiAoSU5URUdSQUxfVFlQRV9QIChUUkVFX1RZUEUgKGFyZzEpKQoJCXx8IFBPSU5URVJfVFlQRV9QIChUUkVFX1RZUEUgKGFyZzEpKSkpCgkgIHsKCSAgICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIHNpZ25lZF9tYXg7CgkgICAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCBtYXgsIG1pbjsKCgkgICAgc2lnbmVkX21heCA9ICgodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgMSA8PCAod2lkdGggLSAxKSkgLSAxOwoKCSAgICBpZiAoVFJFRV9VTlNJR05FRCAoVFJFRV9UWVBFIChhcmcxKSkpCgkgICAgICB7CgkgICAgICAgIG1heCA9ICgodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgMiA8PCAod2lkdGggLSAxKSkgLSAxOwoJCW1pbiA9IDA7CgkgICAgICB9CgkgICAgZWxzZQoJICAgICAgewoJICAgICAgICBtYXggPSBzaWduZWRfbWF4OwoJCW1pbiA9ICgodW5zaWduZWQgSE9TVF9XSURFX0lOVCkgLTEgPDwgKHdpZHRoIC0gMSkpOwoJICAgICAgfQoKCSAgICBpZiAoVFJFRV9JTlRfQ1NUX0hJR0ggKGFyZzEpID09IDAKCQkmJiBUUkVFX0lOVF9DU1RfTE9XIChhcmcxKSA9PSBtYXgpCgkgICAgICBzd2l0Y2ggKGNvZGUpCgkJewoJCWNhc2UgR1RfRVhQUjoKCQkgIHJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLAoJCQkJCSAgIGZvbGRfY29udmVydCAodHlwZSwKCQkJCQkJCSBpbnRlZ2VyX3plcm9fbm9kZSksCgkJCQkJICAgYXJnMCk7CgkJY2FzZSBHRV9FWFBSOgoJCSAgcmV0dXJuIGZvbGQgKGJ1aWxkIChFUV9FWFBSLCB0eXBlLCBhcmcwLCBhcmcxKSk7CgoJCWNhc2UgTEVfRVhQUjoKCQkgIHJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLAoJCQkJCSAgIGZvbGRfY29udmVydCAodHlwZSwKCQkJCQkJCSBpbnRlZ2VyX29uZV9ub2RlKSwKCQkJCQkgICBhcmcwKTsKCQljYXNlIExUX0VYUFI6CgkJICByZXR1cm4gZm9sZCAoYnVpbGQgKE5FX0VYUFIsIHR5cGUsIGFyZzAsIGFyZzEpKTsKCgkJLyogVGhlIEdFX0VYUFIgYW5kIExUX0VYUFIgY2FzZXMgYWJvdmUgYXJlIG5vdCBub3JtYWxseQoJCSAgIHJlYWNoZWQgYmVjYXVzZSBvZiBwcmV2aW91cyB0cmFuc2Zvcm1hdGlvbnMuICAqLwoKCQlkZWZhdWx0OgoJCSAgYnJlYWs7CgkJfQoJICAgIGVsc2UgaWYgKFRSRUVfSU5UX0NTVF9ISUdIIChhcmcxKSA9PSAwCgkJICAgICAmJiBUUkVFX0lOVF9DU1RfTE9XIChhcmcxKSA9PSBtYXggLSAxKQoJICAgICAgc3dpdGNoIChjb2RlKQoJCXsKCQljYXNlIEdUX0VYUFI6CgkJICBhcmcxID0gY29uc3RfYmlub3AgKFBMVVNfRVhQUiwgYXJnMSwgaW50ZWdlcl9vbmVfbm9kZSwgMCk7CgkJICByZXR1cm4gZm9sZCAoYnVpbGQgKEVRX0VYUFIsIHR5cGUsIGFyZzAsIGFyZzEpKTsKCQljYXNlIExFX0VYUFI6CgkJICBhcmcxID0gY29uc3RfYmlub3AgKFBMVVNfRVhQUiwgYXJnMSwgaW50ZWdlcl9vbmVfbm9kZSwgMCk7CgkJICByZXR1cm4gZm9sZCAoYnVpbGQgKE5FX0VYUFIsIHR5cGUsIGFyZzAsIGFyZzEpKTsKCQlkZWZhdWx0OgoJCSAgYnJlYWs7CgkJfQoJICAgIGVsc2UgaWYgKFRSRUVfSU5UX0NTVF9ISUdIIChhcmcxKSA9PSAobWluID8gLTEgOiAwKQoJCSAgICAgJiYgVFJFRV9JTlRfQ1NUX0xPVyAoYXJnMSkgPT0gbWluKQoJICAgICAgc3dpdGNoIChjb2RlKQoJCXsKCQljYXNlIExUX0VYUFI6CgkJICByZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwKCQkJCQkgICBmb2xkX2NvbnZlcnQgKHR5cGUsCgkJCQkJCQkgaW50ZWdlcl96ZXJvX25vZGUpLAoJCQkJCSAgIGFyZzApOwoJCWNhc2UgTEVfRVhQUjoKCQkgIHJldHVybiBmb2xkIChidWlsZCAoRVFfRVhQUiwgdHlwZSwgYXJnMCwgYXJnMSkpOwoKCQljYXNlIEdFX0VYUFI6CgkJICByZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwKCQkJCQkgICBmb2xkX2NvbnZlcnQgKHR5cGUsCgkJCQkJCQkgaW50ZWdlcl9vbmVfbm9kZSksCgkJCQkJICAgYXJnMCk7CgkJY2FzZSBHVF9FWFBSOgoJCSAgcmV0dXJuIGZvbGQgKGJ1aWxkIChORV9FWFBSLCB0eXBlLCBhcmcwLCBhcmcxKSk7CgoJCWRlZmF1bHQ6CgkJICBicmVhazsKCQl9CgkgICAgZWxzZSBpZiAoVFJFRV9JTlRfQ1NUX0hJR0ggKGFyZzEpID09IChtaW4gPyAtMSA6IDApCgkJICAgICAmJiBUUkVFX0lOVF9DU1RfTE9XIChhcmcxKSA9PSBtaW4gKyAxKQoJICAgICAgc3dpdGNoIChjb2RlKQoJCXsKCQljYXNlIEdFX0VYUFI6CgkJICBhcmcxID0gY29uc3RfYmlub3AgKE1JTlVTX0VYUFIsIGFyZzEsIGludGVnZXJfb25lX25vZGUsIDApOwoJCSAgcmV0dXJuIGZvbGQgKGJ1aWxkIChORV9FWFBSLCB0eXBlLCBhcmcwLCBhcmcxKSk7CgkJY2FzZSBMVF9FWFBSOgoJCSAgYXJnMSA9IGNvbnN0X2Jpbm9wIChNSU5VU19FWFBSLCBhcmcxLCBpbnRlZ2VyX29uZV9ub2RlLCAwKTsKCQkgIHJldHVybiBmb2xkIChidWlsZCAoRVFfRVhQUiwgdHlwZSwgYXJnMCwgYXJnMSkpOwoJCWRlZmF1bHQ6CgkJICBicmVhazsKCQl9CgoJICAgIGVsc2UgaWYgKFRSRUVfSU5UX0NTVF9ISUdIIChhcmcxKSA9PSAwCgkJICAgICAmJiBUUkVFX0lOVF9DU1RfTE9XIChhcmcxKSA9PSBzaWduZWRfbWF4CgkJICAgICAmJiBUUkVFX1VOU0lHTkVEIChUUkVFX1RZUEUgKGFyZzEpKQoJCSAgICAgLyogc2lnbmVkX3R5cGUgZG9lcyBub3Qgd29yayBvbiBwb2ludGVyIHR5cGVzLiAgKi8KCQkgICAgICYmIElOVEVHUkFMX1RZUEVfUCAoVFJFRV9UWVBFIChhcmcxKSkpCgkgICAgICB7CgkJLyogVGhlIGZvbGxvd2luZyBjYXNlIGFsc28gYXBwbGllcyB0byBYIDwgc2lnbmVkX21heCsxCgkJICAgYW5kIFggPj0gc2lnbmVkX21heCsxIGJlY2F1c2UgcHJldmlvdXMgdHJhbnNmb3JtYXRpb25zLiAgKi8KCQlpZiAoY29kZSA9PSBMRV9FWFBSIHx8IGNvZGUgPT0gR1RfRVhQUikKCQkgIHsKCQkgICAgdHJlZSBzdDAsIHN0MTsKCQkgICAgc3QwID0gKCpsYW5nX2hvb2tzLnR5cGVzLnNpZ25lZF90eXBlKSAoVFJFRV9UWVBFIChhcmcwKSk7CgkJICAgIHN0MSA9ICgqbGFuZ19ob29rcy50eXBlcy5zaWduZWRfdHlwZSkgKFRSRUVfVFlQRSAoYXJnMSkpOwoJCSAgICByZXR1cm4gZm9sZAoJCSAgICAgIChidWlsZCAoY29kZSA9PSBMRV9FWFBSID8gR0VfRVhQUjogTFRfRVhQUiwKCQkJICAgICAgdHlwZSwgZm9sZF9jb252ZXJ0IChzdDAsIGFyZzApLAoJCQkgICAgICBmb2xkX2NvbnZlcnQgKHN0MSwgaW50ZWdlcl96ZXJvX25vZGUpKSk7CgkJICB9CgkgICAgICB9CgkgIH0KICAgICAgfQoKICAgICAgLyogSWYgdGhpcyBpcyBhbiBFUSBvciBORSBjb21wYXJpc29uIG9mIGEgY29uc3RhbnQgd2l0aCBhIFBMVVNfRVhQUiBvcgoJIGEgTUlOVVNfRVhQUiBvZiBhIGNvbnN0YW50LCB3ZSBjYW4gY29udmVydCBpdCBpbnRvIGEgY29tcGFyaXNvbiB3aXRoCgkgYSByZXZpc2VkIGNvbnN0YW50IGFzIGxvbmcgYXMgbm8gb3ZlcmZsb3cgb2NjdXJzLiAgKi8KICAgICAgaWYgKChjb2RlID09IEVRX0VYUFIgfHwgY29kZSA9PSBORV9FWFBSKQoJICAmJiBUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUCgkgICYmIChUUkVFX0NPREUgKGFyZzApID09IFBMVVNfRVhQUgoJICAgICAgfHwgVFJFRV9DT0RFIChhcmcwKSA9PSBNSU5VU19FWFBSKQoJICAmJiBUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpID09IElOVEVHRVJfQ1NUCgkgICYmIDAgIT0gKHRlbSA9IGNvbnN0X2Jpbm9wIChUUkVFX0NPREUgKGFyZzApID09IFBMVVNfRVhQUgoJCQkJICAgICAgPyBNSU5VU19FWFBSIDogUExVU19FWFBSLAoJCQkJICAgICAgYXJnMSwgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwgMCkpCgkgICYmICEgVFJFRV9DT05TVEFOVF9PVkVSRkxPVyAodGVtKSkKCXJldHVybiBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgdGVtKSk7CgogICAgICAvKiBTaW1pbGFybHkgZm9yIGEgTkVHQVRFX0VYUFIuICAqLwogICAgICBlbHNlIGlmICgoY29kZSA9PSBFUV9FWFBSIHx8IGNvZGUgPT0gTkVfRVhQUikKCSAgICAgICAmJiBUUkVFX0NPREUgKGFyZzApID09IE5FR0FURV9FWFBSCgkgICAgICAgJiYgVFJFRV9DT0RFIChhcmcxKSA9PSBJTlRFR0VSX0NTVAoJICAgICAgICYmIDAgIT0gKHRlbSA9IG5lZ2F0ZV9leHByIChhcmcxKSkKCSAgICAgICAmJiBUUkVFX0NPREUgKHRlbSkgPT0gSU5URUdFUl9DU1QKCSAgICAgICAmJiAhIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKHRlbSkpCglyZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksIHRlbSkpOwoKICAgICAgLyogSWYgd2UgaGF2ZSBYIC0gWSA9PSAwLCB3ZSBjYW4gY29udmVydCB0aGF0IHRvIFggPT0gWSBhbmQgc2ltaWxhcmx5CgkgZm9yICE9LiAgRG9uJ3QgZG8gdGhpcyBmb3Igb3JkZXJlZCBjb21wYXJpc29ucyBkdWUgdG8gb3ZlcmZsb3cuICAqLwogICAgICBlbHNlIGlmICgoY29kZSA9PSBORV9FWFBSIHx8IGNvZGUgPT0gRVFfRVhQUikKCSAgICAgICAmJiBpbnRlZ2VyX3plcm9wIChhcmcxKSAmJiBUUkVFX0NPREUgKGFyZzApID09IE1JTlVTX0VYUFIpCglyZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsCgkJCSAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDApLCBUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSk7CgogICAgICAvKiBJZiB3ZSBhcmUgd2lkZW5pbmcgb25lIG9wZXJhbmQgb2YgYW4gaW50ZWdlciBjb21wYXJpc29uLAoJIHNlZSBpZiB0aGUgb3RoZXIgb3BlcmFuZCBpcyBzaW1pbGFybHkgYmVpbmcgd2lkZW5lZC4gIFBlcmhhcHMgd2UKCSBjYW4gZG8gdGhlIGNvbXBhcmlzb24gaW4gdGhlIG5hcnJvd2VyIHR5cGUuICAqLwogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKFRSRUVfVFlQRSAoYXJnMCkpID09IElOVEVHRVJfVFlQRQoJICAgICAgICYmIFRSRUVfQ09ERSAoYXJnMCkgPT0gTk9QX0VYUFIKCSAgICAgICAmJiAodGVtID0gZ2V0X3Vud2lkZW5lZCAoYXJnMCwgTlVMTF9UUkVFKSkgIT0gYXJnMAoJICAgICAgICYmIChjb2RlID09IEVRX0VYUFIgfHwgY29kZSA9PSBORV9FWFBSCgkJICAgfHwgVFJFRV9VTlNJR05FRCAoVFJFRV9UWVBFIChhcmcwKSkKCQkgICAgICA9PSBUUkVFX1VOU0lHTkVEIChUUkVFX1RZUEUgKHRlbSkpKQoJICAgICAgICYmICh0MSA9IGdldF91bndpZGVuZWQgKGFyZzEsIFRSRUVfVFlQRSAodGVtKSkpICE9IDAKCSAgICAgICAmJiAoVFJFRV9UWVBFICh0MSkgPT0gVFJFRV9UWVBFICh0ZW0pCgkJICAgfHwgKFRSRUVfQ09ERSAodDEpID09IElOVEVHRVJfQ1NUCgkJICAgICAgICYmIGludF9maXRzX3R5cGVfcCAodDEsIFRSRUVfVFlQRSAodGVtKSkpKSkKCXJldHVybiBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwgdGVtLAoJCQkgICAgZm9sZF9jb252ZXJ0IChUUkVFX1RZUEUgKHRlbSksIHQxKSkpOwoKICAgICAgLyogSWYgdGhpcyBpcyBjb21wYXJpbmcgYSBjb25zdGFudCB3aXRoIGEgTUlOX0VYUFIgb3IgYSBNQVhfRVhQUiBvZiBhCgkgY29uc3RhbnQsIHdlIGNhbiBzaW1wbGlmeSBpdC4gICovCiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QKCSAgICAgICAmJiAoVFJFRV9DT0RFIChhcmcwKSA9PSBNSU5fRVhQUgoJCSAgIHx8IFRSRUVfQ09ERSAoYXJnMCkgPT0gTUFYX0VYUFIpCgkgICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSA9PSBJTlRFR0VSX0NTVCkKCXJldHVybiBvcHRpbWl6ZV9taW5tYXhfY29tcGFyaXNvbiAodCk7CgogICAgICAvKiBJZiB3ZSBhcmUgY29tcGFyaW5nIGFuIEFCU19FWFBSIHdpdGggYSBjb25zdGFudCwgd2UgY2FuCgkgY29udmVydCBhbGwgdGhlIGNhc2VzIGludG8gZXhwbGljaXQgY29tcGFyaXNvbnMsIGJ1dCB0aGV5IG1heQoJIHdlbGwgbm90IGJlIGZhc3RlciB0aGFuIGRvaW5nIHRoZSBBQlMgYW5kIG9uZSBjb21wYXJpc29uLgoJIEJ1dCBBQlMgKFgpIDw9IEMgaXMgYSByYW5nZSBjb21wYXJpc29uLCB3aGljaCBiZWNvbWVzIGEgc3VidHJhY3Rpb24KCSBhbmQgYSBjb21wYXJpc29uLCBhbmQgaXMgcHJvYmFibHkgZmFzdGVyLiAgKi8KICAgICAgZWxzZSBpZiAoY29kZSA9PSBMRV9FWFBSICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QKCSAgICAgICAmJiBUUkVFX0NPREUgKGFyZzApID09IEFCU19FWFBSCgkgICAgICAgJiYgISBUUkVFX1NJREVfRUZGRUNUUyAoYXJnMCkKCSAgICAgICAmJiAoMCAhPSAodGVtID0gbmVnYXRlX2V4cHIgKGFyZzEpKSkKCSAgICAgICAmJiBUUkVFX0NPREUgKHRlbSkgPT0gSU5URUdFUl9DU1QKCSAgICAgICAmJiAhIFRSRUVfQ09OU1RBTlRfT1ZFUkZMT1cgKHRlbSkpCglyZXR1cm4gZm9sZCAoYnVpbGQgKFRSVVRIX0FORElGX0VYUFIsIHR5cGUsCgkJCSAgICBidWlsZCAoR0VfRVhQUiwgdHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgdGVtKSwKCQkJICAgIGJ1aWxkIChMRV9FWFBSLCB0eXBlLAoJCQkJICAgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgYXJnMSkpKTsKCiAgICAgIC8qIElmIHRoaXMgaXMgYW4gRVEgb3IgTkUgY29tcGFyaXNvbiB3aXRoIHplcm8gYW5kIEFSRzAgaXMKCSAoMSA8PCBmb28pICYgYmFyLCBjb252ZXJ0IGl0IHRvIChiYXIgPj4gZm9vKSAmIDEuICBCb3RoIHJlcXVpcmUKCSB0d28gb3BlcmF0aW9ucywgYnV0IHRoZSBsYXR0ZXIgY2FuIGJlIGRvbmUgaW4gb25lIGxlc3MgaW5zbgoJIG9uIG1hY2hpbmVzIHRoYXQgaGF2ZSBvbmx5IHR3by1vcGVyYW5kIGluc25zIG9yIG9uIHdoaWNoIGEKCSBjb25zdGFudCBjYW5ub3QgYmUgdGhlIGZpcnN0IG9wZXJhbmQuICAqLwogICAgICBpZiAoaW50ZWdlcl96ZXJvcCAoYXJnMSkgJiYgKGNvZGUgPT0gRVFfRVhQUiB8fCBjb2RlID09IE5FX0VYUFIpCgkgICYmIFRSRUVfQ09ERSAoYXJnMCkgPT0gQklUX0FORF9FWFBSKQoJewoJICBpZiAoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzAsIDApKSA9PSBMU0hJRlRfRVhQUgoJICAgICAgJiYgaW50ZWdlcl9vbmVwIChUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoYXJnMCwgMCksIDApKSkKCSAgICByZXR1cm4KCSAgICAgIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLAoJCQkgICBidWlsZCAoQklUX0FORF9FWFBSLCBUUkVFX1RZUEUgKGFyZzApLAoJCQkJICBidWlsZCAoUlNISUZUX0VYUFIsCgkJCQkJIFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSksCgkJCQkJIFRSRUVfT1BFUkFORCAoYXJnMCwgMSksCgkJCQkJIFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EIChhcmcwLCAwKSwgMSkpLAoJCQkJICBmb2xkX2NvbnZlcnQgKFRSRUVfVFlQRSAoYXJnMCksCgkJCQkJCWludGVnZXJfb25lX25vZGUpKSwKCQkJICAgYXJnMSkpOwoJICBlbHNlIGlmIChUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpID09IExTSElGVF9FWFBSCgkJICAgJiYgaW50ZWdlcl9vbmVwIChUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSksIDApKSkKCSAgICByZXR1cm4KCSAgICAgIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLAoJCQkgICBidWlsZCAoQklUX0FORF9FWFBSLCBUUkVFX1RZUEUgKGFyZzApLAoJCQkJICBidWlsZCAoUlNISUZUX0VYUFIsCgkJCQkJIFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSksCgkJCQkJIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksCgkJCQkJIFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwgMSkpLAoJCQkJICBmb2xkX2NvbnZlcnQgKFRSRUVfVFlQRSAoYXJnMCksCgkJCQkJCWludGVnZXJfb25lX25vZGUpKSwKCQkJICAgYXJnMSkpOwoJfQoKICAgICAgLyogSWYgdGhpcyBpcyBhbiBORSBvciBFUSBjb21wYXJpc29uIG9mIHplcm8gYWdhaW5zdCB0aGUgcmVzdWx0IG9mIGEKCSBzaWduZWQgTU9EIG9wZXJhdGlvbiB3aG9zZSBzZWNvbmQgb3BlcmFuZCBpcyBhIHBvd2VyIG9mIDIsIG1ha2UKCSB0aGUgTU9EIG9wZXJhdGlvbiB1bnNpZ25lZCBzaW5jZSBpdCBpcyBzaW1wbGVyIGFuZCBlcXVpdmFsZW50LiAgKi8KICAgICAgaWYgKChjb2RlID09IE5FX0VYUFIgfHwgY29kZSA9PSBFUV9FWFBSKQoJICAmJiBpbnRlZ2VyX3plcm9wIChhcmcxKQoJICAmJiAhIFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAoYXJnMCkpCgkgICYmIChUUkVFX0NPREUgKGFyZzApID09IFRSVU5DX01PRF9FWFBSCgkgICAgICB8fCBUUkVFX0NPREUgKGFyZzApID09IENFSUxfTU9EX0VYUFIKCSAgICAgIHx8IFRSRUVfQ09ERSAoYXJnMCkgPT0gRkxPT1JfTU9EX0VYUFIKCSAgICAgIHx8IFRSRUVfQ09ERSAoYXJnMCkgPT0gUk9VTkRfTU9EX0VYUFIpCgkgICYmIGludGVnZXJfcG93MnAgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpKQoJewoJICB0cmVlIG5ld3R5cGUgPSAoKmxhbmdfaG9va3MudHlwZXMudW5zaWduZWRfdHlwZSkgKFRSRUVfVFlQRSAoYXJnMCkpOwoJICB0cmVlIG5ld21vZCA9IGJ1aWxkIChUUkVFX0NPREUgKGFyZzApLCBuZXd0eXBlLAoJCQkgICAgICAgZm9sZF9jb252ZXJ0IChuZXd0eXBlLAoJCQkJCSAgICAgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSksCgkJCSAgICAgICBmb2xkX2NvbnZlcnQgKG5ld3R5cGUsCgkJCQkJICAgICBUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSk7CgoJICByZXR1cm4gYnVpbGQgKGNvZGUsIHR5cGUsIG5ld21vZCwgZm9sZF9jb252ZXJ0IChuZXd0eXBlLCBhcmcxKSk7Cgl9CgogICAgICAvKiBJZiB0aGlzIGlzIGFuIE5FIGNvbXBhcmlzb24gb2YgemVybyB3aXRoIGFuIEFORCBvZiBvbmUsIHJlbW92ZSB0aGUKCSBjb21wYXJpc29uIHNpbmNlIHRoZSBBTkQgd2lsbCBnaXZlIHRoZSBjb3JyZWN0IHZhbHVlLiAgKi8KICAgICAgaWYgKGNvZGUgPT0gTkVfRVhQUiAmJiBpbnRlZ2VyX3plcm9wIChhcmcxKQoJICAmJiBUUkVFX0NPREUgKGFyZzApID09IEJJVF9BTkRfRVhQUgoJICAmJiBpbnRlZ2VyX29uZXAgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpKQoJcmV0dXJuIGZvbGRfY29udmVydCAodHlwZSwgYXJnMCk7CgogICAgICAvKiBJZiB3ZSBoYXZlIChBICYgQykgPT0gQyB3aGVyZSBDIGlzIGEgcG93ZXIgb2YgMiwgY29udmVydCB0aGlzIGludG8KCSAoQSAmIEMpICE9IDAuICBTaW1pbGFybHkgZm9yIE5FX0VYUFIuICAqLwogICAgICBpZiAoKGNvZGUgPT0gRVFfRVhQUiB8fCBjb2RlID09IE5FX0VYUFIpCgkgICYmIFRSRUVfQ09ERSAoYXJnMCkgPT0gQklUX0FORF9FWFBSCgkgICYmIGludGVnZXJfcG93MnAgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpCgkgICYmIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwgYXJnMSwgMCkpCglyZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUgPT0gRVFfRVhQUiA/IE5FX0VYUFIgOiBFUV9FWFBSLCB0eXBlLAoJCQkgICAgYXJnMCwgaW50ZWdlcl96ZXJvX25vZGUpKTsKCiAgICAgIC8qIElmIHdlIGhhdmUgKEEgJiBDKSAhPSAwIG9yIChBICYgQykgPT0gMCBhbmQgQyBpcyBhIHBvd2VyIG9mCgkgMiwgdGhlbiBmb2xkIHRoZSBleHByZXNzaW9uIGludG8gc2hpZnRzIGFuZCBsb2dpY2FsIG9wZXJhdGlvbnMuICAqLwogICAgICB0ZW0gPSBmb2xkX3NpbmdsZV9iaXRfdGVzdCAoY29kZSwgYXJnMCwgYXJnMSwgdHlwZSk7CiAgICAgIGlmICh0ZW0pCglyZXR1cm4gdGVtOwoKICAgICAgLyogSWYgd2UgaGF2ZSAoQSAmIEMpID09IEQgd2hlcmUgRCAmIH5DICE9IDAsIGNvbnZlcnQgdGhpcyBpbnRvIDAuCgkgU2ltaWxhcmx5IGZvciBORV9FWFBSLiAgKi8KICAgICAgaWYgKChjb2RlID09IEVRX0VYUFIgfHwgY29kZSA9PSBORV9FWFBSKQoJICAmJiBUUkVFX0NPREUgKGFyZzApID09IEJJVF9BTkRfRVhQUgoJICAmJiBUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkgPT0gSU5URUdFUl9DU1QpCgl7CgkgIHRyZWUgZGFuZG5vdGMKCSAgICA9IGZvbGQgKGJ1aWxkIChCSVRfQU5EX0VYUFIsIFRSRUVfVFlQRSAoYXJnMCksCgkJCSAgIGFyZzEsIGJ1aWxkMSAoQklUX05PVF9FWFBSLAoJCQkJCSBUUkVFX1RZUEUgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpLAoJCQkJCSBUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSkpOwoJICB0cmVlIHJzbHQgPSBjb2RlID09IEVRX0VYUFIgPyBpbnRlZ2VyX3plcm9fbm9kZSA6IGludGVnZXJfb25lX25vZGU7CgkgIGlmIChpbnRlZ2VyX25vbnplcm9wIChkYW5kbm90YykpCgkgICAgcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIHJzbHQsIGFyZzApOwoJfQoKICAgICAgLyogSWYgd2UgaGF2ZSAoQSB8IEMpID09IEQgd2hlcmUgQyAmIH5EICE9IDAsIGNvbnZlcnQgdGhpcyBpbnRvIDAuCgkgU2ltaWxhcmx5IGZvciBORV9FWFBSLiAgKi8KICAgICAgaWYgKChjb2RlID09IEVRX0VYUFIgfHwgY29kZSA9PSBORV9FWFBSKQoJICAmJiBUUkVFX0NPREUgKGFyZzApID09IEJJVF9JT1JfRVhQUgoJICAmJiBUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkgPT0gSU5URUdFUl9DU1QpCgl7CgkgIHRyZWUgY2FuZG5vdGQKCSAgICA9IGZvbGQgKGJ1aWxkIChCSVRfQU5EX0VYUFIsIFRSRUVfVFlQRSAoYXJnMCksCgkJCSAgIFRSRUVfT1BFUkFORCAoYXJnMCwgMSksCgkJCSAgIGJ1aWxkMSAoQklUX05PVF9FWFBSLCBUUkVFX1RZUEUgKGFyZzEpLCBhcmcxKSkpOwoJICB0cmVlIHJzbHQgPSBjb2RlID09IEVRX0VYUFIgPyBpbnRlZ2VyX3plcm9fbm9kZSA6IGludGVnZXJfb25lX25vZGU7CgkgIGlmIChpbnRlZ2VyX25vbnplcm9wIChjYW5kbm90ZCkpCgkgICAgcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIHJzbHQsIGFyZzApOwoJfQoKICAgICAgLyogSWYgWCBpcyB1bnNpZ25lZCwgY29udmVydCBYIDwgKDEgPDwgWSkgaW50byBYID4+IFkgPT0gMAoJIGFuZCBzaW1pbGFybHkgZm9yID49IGludG8gIT0uICAqLwogICAgICBpZiAoKGNvZGUgPT0gTFRfRVhQUiB8fCBjb2RlID09IEdFX0VYUFIpCgkgICYmIFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAoYXJnMCkpCgkgICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gTFNISUZUX0VYUFIKCSAgJiYgaW50ZWdlcl9vbmVwIChUUkVFX09QRVJBTkQgKGFyZzEsIDApKSkKCXJldHVybiBidWlsZCAoY29kZSA9PSBMVF9FWFBSID8gRVFfRVhQUiA6IE5FX0VYUFIsIHR5cGUsCgkJICAgICAgYnVpbGQgKFJTSElGVF9FWFBSLCBUUkVFX1RZUEUgKGFyZzApLCBhcmcwLAoJCQkgICAgIFRSRUVfT1BFUkFORCAoYXJnMSwgMSkpLAoJCSAgICAgIGZvbGRfY29udmVydCAoVFJFRV9UWVBFIChhcmcwKSwgaW50ZWdlcl96ZXJvX25vZGUpKTsKCiAgICAgIGVsc2UgaWYgKChjb2RlID09IExUX0VYUFIgfHwgY29kZSA9PSBHRV9FWFBSKQoJICAgICAgICYmIFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAoYXJnMCkpCgkgICAgICAgJiYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gTk9QX0VYUFIKCQkgICB8fCBUUkVFX0NPREUgKGFyZzEpID09IENPTlZFUlRfRVhQUikKCSAgICAgICAmJiBUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAoYXJnMSwgMCkpID09IExTSElGVF9FWFBSCgkgICAgICAgJiYgaW50ZWdlcl9vbmVwIChUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoYXJnMSwgMCksIDApKSkKCXJldHVybgoJICBidWlsZCAoY29kZSA9PSBMVF9FWFBSID8gRVFfRVhQUiA6IE5FX0VYUFIsIHR5cGUsCgkJIGZvbGRfY29udmVydCAoVFJFRV9UWVBFIChhcmcwKSwKCQkJICAgICAgIGJ1aWxkIChSU0hJRlRfRVhQUiwgVFJFRV9UWVBFIChhcmcwKSwgYXJnMCwKCQkJCSAgICAgIFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EIChhcmcxLCAwKSwKCQkJCQkJICAgIDEpKSksCgkJIGZvbGRfY29udmVydCAoVFJFRV9UWVBFIChhcmcwKSwgaW50ZWdlcl96ZXJvX25vZGUpKTsKCiAgICAgIC8qIFNpbXBsaWZ5IGNvbXBhcmlzb24gb2Ygc29tZXRoaW5nIHdpdGggaXRzZWxmLiAgKEZvciBJRUVFCgkgZmxvYXRpbmctcG9pbnQsIHdlIGNhbiBvbmx5IGRvIHNvbWUgb2YgdGhlc2Ugc2ltcGxpZmljYXRpb25zLikgICovCiAgICAgIGlmIChvcGVyYW5kX2VxdWFsX3AgKGFyZzAsIGFyZzEsIDApKQoJewoJICBzd2l0Y2ggKGNvZGUpCgkgICAgewoJICAgIGNhc2UgRVFfRVhQUjoKCSAgICAgIGlmICghIEZMT0FUX1RZUEVfUCAoVFJFRV9UWVBFIChhcmcwKSkKCQkgIHx8ICEgSE9OT1JfTkFOUyAoVFlQRV9NT0RFIChUUkVFX1RZUEUgKGFyZzApKSkpCgkJcmV0dXJuIGNvbnN0YW50X2Jvb2xlYW5fbm9kZSAoMSwgdHlwZSk7CgkgICAgICBicmVhazsKCgkgICAgY2FzZSBHRV9FWFBSOgoJICAgIGNhc2UgTEVfRVhQUjoKCSAgICAgIGlmICghIEZMT0FUX1RZUEVfUCAoVFJFRV9UWVBFIChhcmcwKSkKCQkgIHx8ICEgSE9OT1JfTkFOUyAoVFlQRV9NT0RFIChUUkVFX1RZUEUgKGFyZzApKSkpCgkJcmV0dXJuIGNvbnN0YW50X2Jvb2xlYW5fbm9kZSAoMSwgdHlwZSk7CgkgICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKEVRX0VYUFIsIHR5cGUsIGFyZzAsIGFyZzEpKTsKCgkgICAgY2FzZSBORV9FWFBSOgoJICAgICAgLyogRm9yIE5FLCB3ZSBjYW4gb25seSBkbyB0aGlzIHNpbXBsaWZpY2F0aW9uIGlmIGludGVnZXIKCQkgb3Igd2UgZG9uJ3QgaG9ub3IgSUVFRSBmbG9hdGluZyBwb2ludCBOYU5zLiAgKi8KCSAgICAgIGlmIChGTE9BVF9UWVBFX1AgKFRSRUVfVFlQRSAoYXJnMCkpCgkJICAmJiBIT05PUl9OQU5TIChUWVBFX01PREUgKFRSRUVfVFlQRSAoYXJnMCkpKSkKCQlicmVhazsKCSAgICAgIC8qIC4uLiBmYWxsIHRocm91Z2ggLi4uICAqLwoJICAgIGNhc2UgR1RfRVhQUjoKCSAgICBjYXNlIExUX0VYUFI6CgkgICAgICByZXR1cm4gY29uc3RhbnRfYm9vbGVhbl9ub2RlICgwLCB0eXBlKTsKCSAgICBkZWZhdWx0OgoJICAgICAgYWJvcnQgKCk7CgkgICAgfQoJfQoKICAgICAgLyogSWYgd2UgYXJlIGNvbXBhcmluZyBhbiBleHByZXNzaW9uIHRoYXQganVzdCBoYXMgY29tcGFyaXNvbnMKCSBvZiB0d28gaW50ZWdlciB2YWx1ZXMsIGFyaXRobWV0aWMgZXhwcmVzc2lvbnMgb2YgdGhvc2UgY29tcGFyaXNvbnMsCgkgYW5kIGNvbnN0YW50cywgd2UgY2FuIHNpbXBsaWZ5IGl0LiAgVGhlcmUgYXJlIG9ubHkgdGhyZWUgY2FzZXMKCSB0byBjaGVjazogdGhlIHR3byB2YWx1ZXMgY2FuIGVpdGhlciBiZSBlcXVhbCwgdGhlIGZpcnN0IGNhbiBiZQoJIGdyZWF0ZXIsIG9yIHRoZSBzZWNvbmQgY2FuIGJlIGdyZWF0ZXIuICBGb2xkIHRoZSBleHByZXNzaW9uIGZvcgoJIHRob3NlIHRocmVlIHZhbHVlcy4gIFNpbmNlIGVhY2ggdmFsdWUgbXVzdCBiZSAwIG9yIDEsIHdlIGhhdmUKCSBlaWdodCBwb3NzaWJpbGl0aWVzLCBlYWNoIG9mIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBjb25zdGFudCAwCgkgb3IgMSBvciBvbmUgb2YgdGhlIHNpeCBwb3NzaWJsZSBjb21wYXJpc29ucy4KCgkgVGhpcyBoYW5kbGVzIGNvbW1vbiBjYXNlcyBsaWtlIChhID4gYikgPT0gMCBidXQgYWxzbyBoYW5kbGVzCgkgZXhwcmVzc2lvbnMgbGlrZSAgKCh4ID4geSkgLSAoeSA+IHgpKSA+IDAsIHdoaWNoIHN1cHBvc2VkbHkKCSBvY2N1ciBpbiBtYWNyb2l6ZWQgY29kZS4gICovCgogICAgICBpZiAoVFJFRV9DT0RFIChhcmcxKSA9PSBJTlRFR0VSX0NTVCAmJiBUUkVFX0NPREUgKGFyZzApICE9IElOVEVHRVJfQ1NUKQoJewoJICB0cmVlIGN2YWwxID0gMCwgY3ZhbDIgPSAwOwoJICBpbnQgc2F2ZV9wID0gMDsKCgkgIGlmICh0d292YWxfY29tcGFyaXNvbl9wIChhcmcwLCAmY3ZhbDEsICZjdmFsMiwgJnNhdmVfcCkKCSAgICAgIC8qIERvbid0IGhhbmRsZSBkZWdlbmVyYXRlIGNhc2VzIGhlcmU7IHRoZXkgc2hvdWxkIGFscmVhZHkKCQkgaGF2ZSBiZWVuIGhhbmRsZWQgYW55d2F5LiAgKi8KCSAgICAgICYmIGN2YWwxICE9IDAgJiYgY3ZhbDIgIT0gMAoJICAgICAgJiYgISAoVFJFRV9DT05TVEFOVCAoY3ZhbDEpICYmIFRSRUVfQ09OU1RBTlQgKGN2YWwyKSkKCSAgICAgICYmIFRSRUVfVFlQRSAoY3ZhbDEpID09IFRSRUVfVFlQRSAoY3ZhbDIpCgkgICAgICAmJiBJTlRFR1JBTF9UWVBFX1AgKFRSRUVfVFlQRSAoY3ZhbDEpKQoJICAgICAgJiYgVFlQRV9NQVhfVkFMVUUgKFRSRUVfVFlQRSAoY3ZhbDEpKQoJICAgICAgJiYgVFlQRV9NQVhfVkFMVUUgKFRSRUVfVFlQRSAoY3ZhbDIpKQoJICAgICAgJiYgISBvcGVyYW5kX2VxdWFsX3AgKFRZUEVfTUlOX1ZBTFVFIChUUkVFX1RZUEUgKGN2YWwxKSksCgkJCQkgICAgVFlQRV9NQVhfVkFMVUUgKFRSRUVfVFlQRSAoY3ZhbDIpKSwgMCkpCgkgICAgewoJICAgICAgdHJlZSBtYXh2YWwgPSBUWVBFX01BWF9WQUxVRSAoVFJFRV9UWVBFIChjdmFsMSkpOwoJICAgICAgdHJlZSBtaW52YWwgPSBUWVBFX01JTl9WQUxVRSAoVFJFRV9UWVBFIChjdmFsMSkpOwoKCSAgICAgIC8qIFdlIGNhbid0IGp1c3QgcGFzcyBUIHRvIGV2YWxfc3Vic3QgaW4gY2FzZSBjdmFsMSBvciBjdmFsMgoJCSB3YXMgdGhlIHNhbWUgYXMgQVJHMS4gICovCgoJICAgICAgdHJlZSBoaWdoX3Jlc3VsdAoJCT0gZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsCgkJCSAgICAgICBldmFsX3N1YnN0IChhcmcwLCBjdmFsMSwgbWF4dmFsLCBjdmFsMiwgbWludmFsKSwKCQkJICAgICAgIGFyZzEpKTsKCSAgICAgIHRyZWUgZXF1YWxfcmVzdWx0CgkJPSBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwKCQkJICAgICAgIGV2YWxfc3Vic3QgKGFyZzAsIGN2YWwxLCBtYXh2YWwsIGN2YWwyLCBtYXh2YWwpLAoJCQkgICAgICAgYXJnMSkpOwoJICAgICAgdHJlZSBsb3dfcmVzdWx0CgkJPSBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwKCQkJICAgICAgIGV2YWxfc3Vic3QgKGFyZzAsIGN2YWwxLCBtaW52YWwsIGN2YWwyLCBtYXh2YWwpLAoJCQkgICAgICAgYXJnMSkpOwoKCSAgICAgIC8qIEFsbCB0aHJlZSBvZiB0aGVzZSByZXN1bHRzIHNob3VsZCBiZSAwIG9yIDEuICBDb25maXJtIHRoZXkKCQkgYXJlLiAgVGhlbiB1c2UgdGhvc2UgdmFsdWVzIHRvIHNlbGVjdCB0aGUgcHJvcGVyIGNvZGUKCQkgdG8gdXNlLiAgKi8KCgkgICAgICBpZiAoKGludGVnZXJfemVyb3AgKGhpZ2hfcmVzdWx0KQoJCSAgIHx8IGludGVnZXJfb25lcCAoaGlnaF9yZXN1bHQpKQoJCSAgJiYgKGludGVnZXJfemVyb3AgKGVxdWFsX3Jlc3VsdCkKCQkgICAgICB8fCBpbnRlZ2VyX29uZXAgKGVxdWFsX3Jlc3VsdCkpCgkJICAmJiAoaW50ZWdlcl96ZXJvcCAobG93X3Jlc3VsdCkKCQkgICAgICB8fCBpbnRlZ2VyX29uZXAgKGxvd19yZXN1bHQpKSkKCQl7CgkJICAvKiBNYWtlIGEgMy1iaXQgbWFzayB3aXRoIHRoZSBoaWdoLW9yZGVyIGJpdCBiZWluZyB0aGUKCQkgICAgIHZhbHVlIGZvciBgPicsIHRoZSBuZXh0IGZvciAnPScsIGFuZCB0aGUgbG93IGZvciAnPCcuICAqLwoJCSAgc3dpdGNoICgoaW50ZWdlcl9vbmVwIChoaWdoX3Jlc3VsdCkgKiA0KQoJCQkgICsgKGludGVnZXJfb25lcCAoZXF1YWxfcmVzdWx0KSAqIDIpCgkJCSAgKyBpbnRlZ2VyX29uZXAgKGxvd19yZXN1bHQpKQoJCSAgICB7CgkJICAgIGNhc2UgMDoKCQkgICAgICAvKiBBbHdheXMgZmFsc2UuICAqLwoJCSAgICAgIHJldHVybiBvbWl0X29uZV9vcGVyYW5kICh0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSwgYXJnMCk7CgkJICAgIGNhc2UgMToKCQkgICAgICBjb2RlID0gTFRfRVhQUjsKCQkgICAgICBicmVhazsKCQkgICAgY2FzZSAyOgoJCSAgICAgIGNvZGUgPSBFUV9FWFBSOwoJCSAgICAgIGJyZWFrOwoJCSAgICBjYXNlIDM6CgkJICAgICAgY29kZSA9IExFX0VYUFI7CgkJICAgICAgYnJlYWs7CgkJICAgIGNhc2UgNDoKCQkgICAgICBjb2RlID0gR1RfRVhQUjsKCQkgICAgICBicmVhazsKCQkgICAgY2FzZSA1OgoJCSAgICAgIGNvZGUgPSBORV9FWFBSOwoJCSAgICAgIGJyZWFrOwoJCSAgICBjYXNlIDY6CgkJICAgICAgY29kZSA9IEdFX0VYUFI7CgkJICAgICAgYnJlYWs7CgkJICAgIGNhc2UgNzoKCQkgICAgICAvKiBBbHdheXMgdHJ1ZS4gICovCgkJICAgICAgcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIGludGVnZXJfb25lX25vZGUsIGFyZzApOwoJCSAgICB9CgoJCSAgdCA9IGJ1aWxkIChjb2RlLCB0eXBlLCBjdmFsMSwgY3ZhbDIpOwoJCSAgaWYgKHNhdmVfcCkKCQkgICAgcmV0dXJuIHNhdmVfZXhwciAodCk7CgkJICBlbHNlCgkJICAgIHJldHVybiBmb2xkICh0KTsKCQl9CgkgICAgfQoJfQoKICAgICAgLyogSWYgdGhpcyBpcyBhIGNvbXBhcmlzb24gb2YgYSBmaWVsZCwgd2UgbWF5IGJlIGFibGUgdG8gc2ltcGxpZnkgaXQuICAqLwogICAgICBpZiAoKChUUkVFX0NPREUgKGFyZzApID09IENPTVBPTkVOVF9SRUYKCSAgICAmJiAoKmxhbmdfaG9va3MuY2FuX3VzZV9iaXRfZmllbGRzX3ApICgpKQoJICAgfHwgVFJFRV9DT0RFIChhcmcwKSA9PSBCSVRfRklFTERfUkVGKQoJICAmJiAoY29kZSA9PSBFUV9FWFBSIHx8IGNvZGUgPT0gTkVfRVhQUikKCSAgLyogSGFuZGxlIHRoZSBjb25zdGFudCBjYXNlIGV2ZW4gd2l0aG91dCAtTwoJICAgICB0byBtYWtlIHN1cmUgdGhlIHdhcm5pbmdzIGFyZSBnaXZlbi4gICovCgkgICYmIChvcHRpbWl6ZSB8fCBUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUKSkKCXsKCSAgdDEgPSBvcHRpbWl6ZV9iaXRfZmllbGRfY29tcGFyZSAoY29kZSwgdHlwZSwgYXJnMCwgYXJnMSk7CgkgIGlmICh0MSkKCSAgICByZXR1cm4gdDE7Cgl9CgogICAgICAvKiBJZiB0aGlzIGlzIGEgY29tcGFyaXNvbiBvZiBjb21wbGV4IHZhbHVlcyBhbmQgZWl0aGVyIG9yIGJvdGggc2lkZXMKCSBhcmUgYSBDT01QTEVYX0VYUFIgb3IgQ09NUExFWF9DU1QsIGl0IGlzIGJlc3QgdG8gc3BsaXQgdXAgdGhlCgkgY29tcGFyaXNvbnMgYW5kIGpvaW4gdGhlbSB3aXRoIGEgVFJVVEhfQU5ESUZfRVhQUiBvciBUUlVUSF9PUklGX0VYUFIuCgkgVGhpcyBtYXkgcHJldmVudCBuZWVkbGVzcyBldmFsdWF0aW9ucy4gICovCiAgICAgIGlmICgoY29kZSA9PSBFUV9FWFBSIHx8IGNvZGUgPT0gTkVfRVhQUikKCSAgJiYgVFJFRV9DT0RFIChUUkVFX1RZUEUgKGFyZzApKSA9PSBDT01QTEVYX1RZUEUKCSAgJiYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQ09NUExFWF9FWFBSCgkgICAgICB8fCBUUkVFX0NPREUgKGFyZzEpID09IENPTVBMRVhfRVhQUgoJICAgICAgfHwgVFJFRV9DT0RFIChhcmcwKSA9PSBDT01QTEVYX0NTVAoJICAgICAgfHwgVFJFRV9DT0RFIChhcmcxKSA9PSBDT01QTEVYX0NTVCkpCgl7CgkgIHRyZWUgc3VidHlwZSA9IFRSRUVfVFlQRSAoVFJFRV9UWVBFIChhcmcwKSk7CgkgIHRyZWUgcmVhbDAsIGltYWcwLCByZWFsMSwgaW1hZzE7CgoJICBhcmcwID0gc2F2ZV9leHByIChhcmcwKTsKCSAgYXJnMSA9IHNhdmVfZXhwciAoYXJnMSk7CgkgIHJlYWwwID0gZm9sZCAoYnVpbGQxIChSRUFMUEFSVF9FWFBSLCBzdWJ0eXBlLCBhcmcwKSk7CgkgIGltYWcwID0gZm9sZCAoYnVpbGQxIChJTUFHUEFSVF9FWFBSLCBzdWJ0eXBlLCBhcmcwKSk7CgkgIHJlYWwxID0gZm9sZCAoYnVpbGQxIChSRUFMUEFSVF9FWFBSLCBzdWJ0eXBlLCBhcmcxKSk7CgkgIGltYWcxID0gZm9sZCAoYnVpbGQxIChJTUFHUEFSVF9FWFBSLCBzdWJ0eXBlLCBhcmcxKSk7CgoJICByZXR1cm4gZm9sZCAoYnVpbGQgKChjb2RlID09IEVRX0VYUFIgPyBUUlVUSF9BTkRJRl9FWFBSCgkJCSAgICAgICA6IFRSVVRIX09SSUZfRVhQUiksCgkJCSAgICAgIHR5cGUsCgkJCSAgICAgIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLCByZWFsMCwgcmVhbDEpKSwKCQkJICAgICAgZm9sZCAoYnVpbGQgKGNvZGUsIHR5cGUsIGltYWcwLCBpbWFnMSkpKSk7Cgl9CgogICAgICAvKiBPcHRpbWl6ZSBjb21wYXJpc29ucyBvZiBzdHJsZW4gdnMgemVybyB0byBhIGNvbXBhcmUgb2YgdGhlCgkgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcgdnMgemVyby4gIFRvIHdpdCwKCQlzdHJsZW4ocHRyKSA9PSAwICAgPT4gICpwdHIgPT0gMAoJCXN0cmxlbihwdHIpICE9IDAgICA9PiAgKnB0ciAhPSAwCgkgT3RoZXIgY2FzZXMgc2hvdWxkIHJlZHVjZSB0byBvbmUgb2YgdGhlc2UgdHdvIChvciBhIGNvbnN0YW50KQoJIGR1ZSB0byB0aGUgcmV0dXJuIHZhbHVlIG9mIHN0cmxlbiBiZWluZyB1bnNpZ25lZC4gICovCiAgICAgIGlmICgoY29kZSA9PSBFUV9FWFBSIHx8IGNvZGUgPT0gTkVfRVhQUikKCSAgJiYgaW50ZWdlcl96ZXJvcCAoYXJnMSkKCSAgJiYgVFJFRV9DT0RFIChhcmcwKSA9PSBDQUxMX0VYUFIpCgl7CgkgIHRyZWUgZm5kZWNsID0gZ2V0X2NhbGxlZV9mbmRlY2wgKGFyZzApOwoJICB0cmVlIGFyZ2xpc3Q7CgoJICBpZiAoZm5kZWNsCgkgICAgICAmJiBERUNMX0JVSUxUX0lOIChmbmRlY2wpCgkgICAgICAmJiBERUNMX0JVSUxUX0lOX0NMQVNTIChmbmRlY2wpICE9IEJVSUxUX0lOX01ECgkgICAgICAmJiBERUNMX0ZVTkNUSU9OX0NPREUgKGZuZGVjbCkgPT0gQlVJTFRfSU5fU1RSTEVOCgkgICAgICAmJiAoYXJnbGlzdCA9IFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpCgkgICAgICAmJiBUUkVFX0NPREUgKFRSRUVfVFlQRSAoVFJFRV9WQUxVRSAoYXJnbGlzdCkpKSA9PSBQT0lOVEVSX1RZUEUKCSAgICAgICYmICEgVFJFRV9DSEFJTiAoYXJnbGlzdCkpCgkgICAgcmV0dXJuIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLAoJCQkJYnVpbGQxIChJTkRJUkVDVF9SRUYsIGNoYXJfdHlwZV9ub2RlLAoJCQkJCVRSRUVfVkFMVUUoYXJnbGlzdCkpLAoJCQkJaW50ZWdlcl96ZXJvX25vZGUpKTsKCX0KCiAgICAgIC8qIEZyb20gaGVyZSBvbiwgdGhlIG9ubHkgY2FzZXMgd2UgaGFuZGxlIGFyZSB3aGVuIHRoZSByZXN1bHQgaXMKCSBrbm93biB0byBiZSBhIGNvbnN0YW50LgoKCSBUbyBjb21wdXRlIEdULCBzd2FwIHRoZSBhcmd1bWVudHMgYW5kIGRvIExULgoJIFRvIGNvbXB1dGUgR0UsIGRvIExUIGFuZCBpbnZlcnQgdGhlIHJlc3VsdC4KCSBUbyBjb21wdXRlIExFLCBzd2FwIHRoZSBhcmd1bWVudHMsIGRvIExUIGFuZCBpbnZlcnQgdGhlIHJlc3VsdC4KCSBUbyBjb21wdXRlIE5FLCBkbyBFUSBhbmQgaW52ZXJ0IHRoZSByZXN1bHQuCgoJIFRoZXJlZm9yZSwgdGhlIGNvZGUgYmVsb3cgbXVzdCBoYW5kbGUgb25seSBFUSBhbmQgTFQuICAqLwoKICAgICAgaWYgKGNvZGUgPT0gTEVfRVhQUiB8fCBjb2RlID09IEdUX0VYUFIpCgl7CgkgIHRlbSA9IGFyZzAsIGFyZzAgPSBhcmcxLCBhcmcxID0gdGVtOwoJICBjb2RlID0gc3dhcF90cmVlX2NvbXBhcmlzb24gKGNvZGUpOwoJfQoKICAgICAgLyogTm90ZSB0aGF0IGl0IGlzIHNhZmUgdG8gaW52ZXJ0IGZvciByZWFsIHZhbHVlcyBoZXJlIGJlY2F1c2Ugd2UKCSB3aWxsIGNoZWNrIGJlbG93IGluIHRoZSBvbmUgY2FzZSB0aGF0IGl0IG1hdHRlcnMuICAqLwoKICAgICAgdDEgPSBOVUxMX1RSRUU7CiAgICAgIGludmVydCA9IDA7CiAgICAgIGlmIChjb2RlID09IE5FX0VYUFIgfHwgY29kZSA9PSBHRV9FWFBSKQoJewoJICBpbnZlcnQgPSAxOwoJICBjb2RlID0gaW52ZXJ0X3RyZWVfY29tcGFyaXNvbiAoY29kZSk7Cgl9CgogICAgICAvKiBDb21wdXRlIGEgcmVzdWx0IGZvciBMVCBvciBFUSBpZiBhcmdzIHBlcm1pdDsKCSBvdGhlcndpc2UgcmV0dXJuIFQuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBJTlRFR0VSX0NTVCAmJiBUUkVFX0NPREUgKGFyZzEpID09IElOVEVHRVJfQ1NUKQoJewoJICBpZiAoY29kZSA9PSBFUV9FWFBSKQoJICAgIHQxID0gYnVpbGRfaW50XzIgKHRyZWVfaW50X2NzdF9lcXVhbCAoYXJnMCwgYXJnMSksIDApOwoJICBlbHNlCgkgICAgdDEgPSBidWlsZF9pbnRfMiAoKFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAoYXJnMCkpCgkJCSAgICAgICA/IElOVF9DU1RfTFRfVU5TSUdORUQgKGFyZzAsIGFyZzEpCgkJCSAgICAgICA6IElOVF9DU1RfTFQgKGFyZzAsIGFyZzEpKSwKCQkJICAgICAgMCk7Cgl9CgojaWYgMCAvKiBUaGlzIGlzIG5vIGxvbmdlciB1c2VmdWwsIGJ1dCBicmVha3Mgc29tZSByZWFsIGNvZGUuICAqLwogICAgICAvKiBBc3N1bWUgYSBub25leHBsaWNpdCBjb25zdGFudCBjYW5ub3QgZXF1YWwgYW4gZXhwbGljaXQgb25lLAoJIHNpbmNlIHN1Y2ggY29kZSB3b3VsZCBiZSB1bmRlZmluZWQgYW55d2F5LgoJIEV4Y2VwdGlvbjogb24gc3lzdnI0LCB1c2luZyAjcHJhZ21hIHdlYWssCgkgYSBsYWJlbCBjYW4gY29tZSBvdXQgYXMgMC4gICovCiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnMSkgPT0gSU5URUdFUl9DU1QKCSAgICAgICAmJiAhaW50ZWdlcl96ZXJvcCAoYXJnMSkKCSAgICAgICAmJiBUUkVFX0NPTlNUQU5UIChhcmcwKQoJICAgICAgICYmIFRSRUVfQ09ERSAoYXJnMCkgPT0gQUREUl9FWFBSCgkgICAgICAgJiYgY29kZSA9PSBFUV9FWFBSKQoJdDEgPSBidWlsZF9pbnRfMiAoMCwgMCk7CiNlbmRpZgogICAgICAvKiBUd28gcmVhbCBjb25zdGFudHMgY2FuIGJlIGNvbXBhcmVkIGV4cGxpY2l0bHkuICAqLwogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKGFyZzApID09IFJFQUxfQ1NUICYmIFRSRUVfQ09ERSAoYXJnMSkgPT0gUkVBTF9DU1QpCgl7CgkgIC8qIElmIGVpdGhlciBvcGVyYW5kIGlzIGEgTmFOLCB0aGUgcmVzdWx0IGlzIGZhbHNlIHdpdGggdHdvCgkgICAgIGV4Y2VwdGlvbnM6IEZpcnN0LCBhbiBORV9FWFBSIGlzIHRydWUgb24gTmFOcywgYnV0IHRoYXQgY2FzZQoJICAgICBpcyBhbHJlYWR5IGhhbmRsZWQgY29ycmVjdGx5IHNpbmNlIHdlIHdpbGwgYmUgaW52ZXJ0aW5nIHRoZQoJICAgICByZXN1bHQgZm9yIE5FX0VYUFIuICBTZWNvbmQsIGlmIHdlIGhhZCBpbnZlcnRlZCBhIExFX0VYUFIKCSAgICAgb3IgYSBHRV9FWFBSIGludG8gYSBMVF9FWFBSLCB3ZSBtdXN0IHJldHVybiB0cnVlIHNvIHRoYXQgaXQKCSAgICAgd2lsbCBiZSBpbnZlcnRlZCBpbnRvIGZhbHNlLiAgKi8KCgkgIGlmIChSRUFMX1ZBTFVFX0lTTkFOIChUUkVFX1JFQUxfQ1NUIChhcmcwKSkKCSAgICAgIHx8IFJFQUxfVkFMVUVfSVNOQU4gKFRSRUVfUkVBTF9DU1QgKGFyZzEpKSkKCSAgICB0MSA9IGJ1aWxkX2ludF8yIChpbnZlcnQgJiYgY29kZSA9PSBMVF9FWFBSLCAwKTsKCgkgIGVsc2UgaWYgKGNvZGUgPT0gRVFfRVhQUikKCSAgICB0MSA9IGJ1aWxkX2ludF8yIChSRUFMX1ZBTFVFU19FUVVBTCAoVFJFRV9SRUFMX0NTVCAoYXJnMCksCgkJCQkJCSBUUkVFX1JFQUxfQ1NUIChhcmcxKSksCgkJCSAgICAgIDApOwoJICBlbHNlCgkgICAgdDEgPSBidWlsZF9pbnRfMiAoUkVBTF9WQUxVRVNfTEVTUyAoVFJFRV9SRUFMX0NTVCAoYXJnMCksCgkJCQkJCVRSRUVfUkVBTF9DU1QgKGFyZzEpKSwKCQkJICAgICAgMCk7Cgl9CgogICAgICBpZiAodDEgPT0gTlVMTF9UUkVFKQoJcmV0dXJuIHQ7CgogICAgICBpZiAoaW52ZXJ0KQoJVFJFRV9JTlRfQ1NUX0xPVyAodDEpIF49IDE7CgogICAgICBUUkVFX1RZUEUgKHQxKSA9IHR5cGU7CiAgICAgIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEJPT0xFQU5fVFlQRSkKCXJldHVybiAoKmxhbmdfaG9va3MudHJ1dGh2YWx1ZV9jb252ZXJzaW9uKSAodDEpOwogICAgICByZXR1cm4gdDE7CgogICAgY2FzZSBDT05EX0VYUFI6CiAgICAgIC8qIFBlZGFudGljIEFOU0kgQyBzYXlzIHRoYXQgYSBjb25kaXRpb25hbCBleHByZXNzaW9uIGlzIG5ldmVyIGFuIGx2YWx1ZSwKCSBzbyBhbGwgc2ltcGxlIHJlc3VsdHMgbXVzdCBiZSBwYXNzZWQgdGhyb3VnaCBwZWRhbnRpY19ub25fbHZhbHVlLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gSU5URUdFUl9DU1QpCgl7CgkgIHRlbSA9IFRSRUVfT1BFUkFORCAodCwgKGludGVnZXJfemVyb3AgKGFyZzApID8gMiA6IDEpKTsKCSAgLyogT25seSBvcHRpbWl6ZSBjb25zdGFudCBjb25kaXRpb25zIHdoZW4gdGhlIHNlbGVjdGVkIGJyYW5jaAoJICAgICBoYXMgdGhlIHNhbWUgdHlwZSBhcyB0aGUgQ09ORF9FWFBSLiAgVGhpcyBhdm9pZHMgb3B0aW1pemluZwoJICAgICBhd2F5ICJjID8geCA6IHRocm93Iiwgd2hlcmUgdGhlIHRocm93IGhhcyBhIHZvaWQgdHlwZS4gICovCgkgIGlmICghIFZPSURfVFlQRV9QIChUUkVFX1RZUEUgKHRlbSkpCgkgICAgICB8fCBWT0lEX1RZUEVfUCAoVFJFRV9UWVBFICh0KSkpCgkgICAgcmV0dXJuIHBlZGFudGljX25vbl9sdmFsdWUgKHRlbSk7CgkgIHJldHVybiB0OwoJfQogICAgICBpZiAob3BlcmFuZF9lcXVhbF9wIChhcmcxLCBUUkVFX09QRVJBTkQgKGV4cHIsIDIpLCAwKSkKCXJldHVybiBwZWRhbnRpY19vbWl0X29uZV9vcGVyYW5kICh0eXBlLCBhcmcxLCBhcmcwKTsKCiAgICAgIC8qIElmIHdlIGhhdmUgQSBvcCBCID8gQSA6IEMsIHdlIG1heSBiZSBhYmxlIHRvIGNvbnZlcnQgdGhpcyB0byBhCgkgc2ltcGxlciBleHByZXNzaW9uLCBkZXBlbmRpbmcgb24gdGhlIG9wZXJhdGlvbiBhbmQgdGhlIHZhbHVlcwoJIG9mIEIgYW5kIEMuICBTaWduZWQgemVyb3MgcHJldmVudCBhbGwgb2YgdGhlc2UgdHJhbnNmb3JtYXRpb25zLAoJIGZvciByZWFzb25zIGdpdmVuIGFib3ZlIGVhY2ggb25lLiAgKi8KCiAgICAgIGlmIChUUkVFX0NPREVfQ0xBU1MgKFRSRUVfQ09ERSAoYXJnMCkpID09ICc8JwoJICAmJiBvcGVyYW5kX2VxdWFsX2Zvcl9jb21wYXJpc29uX3AgKFRSRUVfT1BFUkFORCAoYXJnMCwgMCksCgkJCQkJICAgICBhcmcxLCBUUkVFX09QRVJBTkQgKGFyZzAsIDEpKQoJICAmJiAhSE9OT1JfU0lHTkVEX1pFUk9TIChUWVBFX01PREUgKFRSRUVfVFlQRSAoYXJnMSkpKSkKCXsKCSAgdHJlZSBhcmcyID0gVFJFRV9PUEVSQU5EICh0LCAyKTsKCSAgZW51bSB0cmVlX2NvZGUgY29tcF9jb2RlID0gVFJFRV9DT0RFIChhcmcwKTsKCgkgIFNUUklQX05PUFMgKGFyZzIpOwoKCSAgLyogSWYgd2UgaGF2ZSBBIG9wIDAgPyBBIDogLUEsIGNvbnNpZGVyIGFwcGx5aW5nIHRoZSBmb2xsb3dpbmcKCSAgICAgdHJhbnNmb3JtYXRpb25zOgoKCSAgICAgQSA9PSAwPyBBIDogLUEgICAgc2FtZSBhcyAtQQoJICAgICBBICE9IDA/IEEgOiAtQSAgICBzYW1lIGFzIEEKCSAgICAgQSA+PSAwPyBBIDogLUEgICAgc2FtZSBhcyBhYnMgKEEpCgkgICAgIEEgPiAwPyAgQSA6IC1BICAgIHNhbWUgYXMgYWJzIChBKQoJICAgICBBIDw9IDA/IEEgOiAtQSAgICBzYW1lIGFzIC1hYnMgKEEpCgkgICAgIEEgPCAwPyAgQSA6IC1BICAgIHNhbWUgYXMgLWFicyAoQSkKCgkgICAgIE5vbmUgb2YgdGhlc2UgdHJhbnNmb3JtYXRpb25zIHdvcmsgZm9yIG1vZGVzIHdpdGggc2lnbmVkCgkgICAgIHplcm9zLiAgSWYgQSBpcyArLy0wLCB0aGUgZmlyc3QgdHdvIHRyYW5zZm9ybWF0aW9ucyB3aWxsCgkgICAgIGNoYW5nZSB0aGUgc2lnbiBvZiB0aGUgcmVzdWx0IChmcm9tICswIHRvIC0wLCBvciB2aWNlCgkgICAgIHZlcnNhKS4gIFRoZSBsYXN0IGZvdXIgd2lsbCBmaXggdGhlIHNpZ24gb2YgdGhlIHJlc3VsdCwKCSAgICAgZXZlbiB0aG91Z2ggdGhlIG9yaWdpbmFsIGV4cHJlc3Npb25zIGNvdWxkIGJlIHBvc2l0aXZlIG9yCgkgICAgIG5lZ2F0aXZlLCBkZXBlbmRpbmcgb24gdGhlIHNpZ24gb2YgQS4KCgkgICAgIE5vdGUgdGhhdCBhbGwgdGhlc2UgdHJhbnNmb3JtYXRpb25zIGFyZSBjb3JyZWN0IGlmIEEgaXMKCSAgICAgTmFOLCBzaW5jZSB0aGUgdHdvIGFsdGVybmF0aXZlcyAoQSBhbmQgLUEpIGFyZSBhbHNvIE5hTnMuICAqLwoJICBpZiAoKEZMT0FUX1RZUEVfUCAoVFJFRV9UWVBFIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSkKCSAgICAgICA/IHJlYWxfemVyb3AgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpCgkgICAgICAgOiBpbnRlZ2VyX3plcm9wIChUUkVFX09QRVJBTkQgKGFyZzAsIDEpKSkKCSAgICAgICYmIFRSRUVfQ09ERSAoYXJnMikgPT0gTkVHQVRFX0VYUFIKCSAgICAgICYmIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcyLCAwKSwgYXJnMSwgMCkpCgkgICAgc3dpdGNoIChjb21wX2NvZGUpCgkgICAgICB7CgkgICAgICBjYXNlIEVRX0VYUFI6CgkJdGVtID0gZm9sZF9jb252ZXJ0IChUUkVFX1RZUEUgKFRSRUVfT1BFUkFORCAodCwgMSkpLCBhcmcxKTsKCQl0ZW0gPSBmb2xkX2NvbnZlcnQgKHR5cGUsIG5lZ2F0ZV9leHByICh0ZW0pKTsKCQlyZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZSAodGVtKTsKCSAgICAgIGNhc2UgTkVfRVhQUjoKCQlyZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcxKSk7CgkgICAgICBjYXNlIEdFX0VYUFI6CgkgICAgICBjYXNlIEdUX0VYUFI6CgkJaWYgKFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAoYXJnMSkpKQoJCSAgYXJnMSA9IGZvbGRfY29udmVydCAoKCpsYW5nX2hvb2tzLnR5cGVzLnNpZ25lZF90eXBlKQoJCQkJICAgICAgIChUUkVFX1RZUEUgKGFyZzEpKSwgYXJnMSk7CgkJYXJnMSA9IGZvbGQgKGJ1aWxkMSAoQUJTX0VYUFIsIFRSRUVfVFlQRSAoYXJnMSksIGFyZzEpKTsKCQlyZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcxKSk7CgkgICAgICBjYXNlIExFX0VYUFI6CgkgICAgICBjYXNlIExUX0VYUFI6CgkJaWYgKFRSRUVfVU5TSUdORUQgKFRSRUVfVFlQRSAoYXJnMSkpKQoJCSAgYXJnMSA9IGZvbGRfY29udmVydCAoKGxhbmdfaG9va3MudHlwZXMuc2lnbmVkX3R5cGUpCgkJCQkgICAgICAgKFRSRUVfVFlQRSAoYXJnMSkpLCBhcmcxKTsKCQlhcmcxID0gZm9sZCAoYnVpbGQxIChBQlNfRVhQUiwgVFJFRV9UWVBFIChhcmcxKSwgYXJnMSkpOwoJCWFyZzEgPSBuZWdhdGVfZXhwciAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcxKSk7CgkJcmV0dXJuIHBlZGFudGljX25vbl9sdmFsdWUgKGFyZzEpOwoJICAgICAgZGVmYXVsdDoKCQlhYm9ydCAoKTsKCSAgICAgIH0KCgkgIC8qIEEgIT0gMCA/IEEgOiAwIGlzIHNpbXBseSBBLCB1bmxlc3MgQSBpcyAtMC4gIExpa2V3aXNlCgkgICAgIEEgPT0gMCA/IEEgOiAwIGlzIGFsd2F5cyAwIHVubGVzcyBBIGlzIC0wLiAgTm90ZSB0aGF0CgkgICAgIGJvdGggdHJhbnNmb3JtYXRpb25zIGFyZSBjb3JyZWN0IHdoZW4gQSBpcyBOYU46IEEgIT0gMAoJICAgICBpcyB0aGVuIHRydWUsIGFuZCBBID09IDAgaXMgZmFsc2UuICAqLwoKCSAgaWYgKGludGVnZXJfemVyb3AgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpICYmIGludGVnZXJfemVyb3AgKGFyZzIpKQoJICAgIHsKCSAgICAgIGlmIChjb21wX2NvZGUgPT0gTkVfRVhQUikKCQlyZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcxKSk7CgkgICAgICBlbHNlIGlmIChjb21wX2NvZGUgPT0gRVFfRVhQUikKCQlyZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0ICh0eXBlLCBpbnRlZ2VyX3plcm9fbm9kZSkpOwoJICAgIH0KCgkgIC8qIFRyeSBzb21lIHRyYW5zZm9ybWF0aW9ucyBvZiBBIG9wIEIgPyBBIDogQi4KCgkgICAgIEEgPT0gQj8gQSA6IEIgICAgc2FtZSBhcyBCCgkgICAgIEEgIT0gQj8gQSA6IEIgICAgc2FtZSBhcyBBCgkgICAgIEEgPj0gQj8gQSA6IEIgICAgc2FtZSBhcyBtYXggKEEsIEIpCgkgICAgIEEgPiBCPyAgQSA6IEIgICAgc2FtZSBhcyBtYXggKEIsIEEpCgkgICAgIEEgPD0gQj8gQSA6IEIgICAgc2FtZSBhcyBtaW4gKEEsIEIpCgkgICAgIEEgPCBCPyAgQSA6IEIgICAgc2FtZSBhcyBtaW4gKEIsIEEpCgoJICAgICBBcyBhYm92ZSwgdGhlc2UgdHJhbnNmb3JtYXRpb25zIGRvbid0IHdvcmsgaW4gdGhlIHByZXNlbmNlCgkgICAgIG9mIHNpZ25lZCB6ZXJvcy4gIEZvciBleGFtcGxlLCBpZiBBIGFuZCBCIGFyZSB6ZXJvcyBvZgoJICAgICBvcHBvc2l0ZSBzaWduLCB0aGUgZmlyc3QgdHdvIHRyYW5zZm9ybWF0aW9ucyB3aWxsIGNoYW5nZQoJICAgICB0aGUgc2lnbiBvZiB0aGUgcmVzdWx0LiAgSW4gdGhlIGxhc3QgZm91ciwgdGhlIG9yaWdpbmFsCgkgICAgIGV4cHJlc3Npb25zIGdpdmUgZGlmZmVyZW50IHJlc3VsdHMgZm9yIChBPSswLCBCPS0wKSBhbmQKCSAgICAgKEE9LTAsIEI9KzApLCBidXQgdGhlIHRyYW5zZm9ybWVkIGV4cHJlc3Npb25zIGRvIG5vdC4KCgkgICAgIFRoZSBmaXJzdCB0d28gdHJhbnNmb3JtYXRpb25zIGFyZSBjb3JyZWN0IGlmIGVpdGhlciBBIG9yIEIKCSAgICAgaXMgYSBOYU4uICBJbiB0aGUgZmlyc3QgdHJhbnNmb3JtYXRpb24sIHRoZSBjb25kaXRpb24gd2lsbAoJICAgICBiZSBmYWxzZSwgYW5kIEIgd2lsbCBpbmRlZWQgYmUgY2hvc2VuLiAgSW4gdGhlIGNhc2Ugb2YgdGhlCgkgICAgIHNlY29uZCB0cmFuc2Zvcm1hdGlvbiwgdGhlIGNvbmRpdGlvbiBBICE9IEIgd2lsbCBiZSB0cnVlLAoJICAgICBhbmQgQSB3aWxsIGJlIGNob3Nlbi4KCgkgICAgIFRoZSBjb252ZXJzaW9ucyB0byBtYXgoKSBhbmQgbWluKCkgYXJlIG5vdCBjb3JyZWN0IGlmIEIgaXMKCSAgICAgYSBudW1iZXIgYW5kIEEgaXMgbm90LiAgVGhlIGNvbmRpdGlvbnMgaW4gdGhlIG9yaWdpbmFsCgkgICAgIGV4cHJlc3Npb25zIHdpbGwgYmUgZmFsc2UsIHNvIGFsbCBmb3VyIGdpdmUgQi4gIFRoZSBtaW4oKQoJICAgICBhbmQgbWF4KCkgdmVyc2lvbnMgd291bGQgZ2l2ZSBhIE5hTiBpbnN0ZWFkLiAgKi8KCSAgaWYgKG9wZXJhbmRfZXF1YWxfZm9yX2NvbXBhcmlzb25fcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwKCQkJCQkgICAgICBhcmcyLCBUUkVFX09QRVJBTkQgKGFyZzAsIDApKSkKCSAgICB7CgkgICAgICB0cmVlIGNvbXBfb3AwID0gVFJFRV9PUEVSQU5EIChhcmcwLCAwKTsKCSAgICAgIHRyZWUgY29tcF9vcDEgPSBUUkVFX09QRVJBTkQgKGFyZzAsIDEpOwoJICAgICAgdHJlZSBjb21wX3R5cGUgPSBUUkVFX1RZUEUgKGNvbXBfb3AwKTsKCgkgICAgICAvKiBBdm9pZCBhZGRpbmcgTk9QX0VYUFJzIGluIGNhc2UgdGhpcyBpcyBhbiBsdmFsdWUuICAqLwoJICAgICAgaWYgKFRZUEVfTUFJTl9WQVJJQU5UIChjb21wX3R5cGUpID09IFRZUEVfTUFJTl9WQVJJQU5UICh0eXBlKSkKCQl7CgkJICBjb21wX3R5cGUgPSB0eXBlOwoJCSAgY29tcF9vcDAgPSBhcmcxOwoJCSAgY29tcF9vcDEgPSBhcmcyOwoJCX0KCgkgICAgICBzd2l0Y2ggKGNvbXBfY29kZSkKCQl7CgkJY2FzZSBFUV9FWFBSOgoJCSAgcmV0dXJuIHBlZGFudGljX25vbl9sdmFsdWUgKGZvbGRfY29udmVydCAodHlwZSwgYXJnMikpOwoJCWNhc2UgTkVfRVhQUjoKCQkgIHJldHVybiBwZWRhbnRpY19ub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsIGFyZzEpKTsKCQljYXNlIExFX0VYUFI6CgkJY2FzZSBMVF9FWFBSOgoJCSAgLyogSW4gQysrIGEgPzogZXhwcmVzc2lvbiBjYW4gYmUgYW4gbHZhbHVlLCBzbyBwdXQgdGhlCgkJICAgICBvcGVyYW5kIHdoaWNoIHdpbGwgYmUgdXNlZCBpZiB0aGV5IGFyZSBlcXVhbCBmaXJzdAoJCSAgICAgc28gdGhhdCB3ZSBjYW4gY29udmVydCB0aGlzIGJhY2sgdG8gdGhlCgkJICAgICBjb3JyZXNwb25kaW5nIENPTkRfRVhQUi4gICovCgkJICBpZiAoIUhPTk9SX05BTlMgKFRZUEVfTU9ERSAoVFJFRV9UWVBFIChhcmcxKSkpKQoJCSAgICByZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZSAoZm9sZF9jb252ZXJ0CgkJICAgICAgKHR5cGUsIGZvbGQgKGJ1aWxkIChNSU5fRVhQUiwgY29tcF90eXBlLAoJCQkJCSAgKGNvbXBfY29kZSA9PSBMRV9FWFBSCgkJCQkJICAgPyBjb21wX29wMCA6IGNvbXBfb3AxKSwKCQkJCQkgIChjb21wX2NvZGUgPT0gTEVfRVhQUgoJCQkJCSAgID8gY29tcF9vcDEgOiBjb21wX29wMCkpKSkpOwoJCSAgYnJlYWs7CgkJY2FzZSBHRV9FWFBSOgoJCWNhc2UgR1RfRVhQUjoKCQkgIGlmICghSE9OT1JfTkFOUyAoVFlQRV9NT0RFIChUUkVFX1RZUEUgKGFyZzEpKSkpCgkJICAgIHJldHVybiBwZWRhbnRpY19ub25fbHZhbHVlIChmb2xkX2NvbnZlcnQKCQkgICAgICAodHlwZSwgZm9sZCAoYnVpbGQgKE1BWF9FWFBSLCBjb21wX3R5cGUsCgkJCQkJICAoY29tcF9jb2RlID09IEdFX0VYUFIKCQkJCQkgICA/IGNvbXBfb3AwIDogY29tcF9vcDEpLAoJCQkJCSAgKGNvbXBfY29kZSA9PSBHRV9FWFBSCgkJCQkJICAgPyBjb21wX29wMSA6IGNvbXBfb3AwKSkpKSk7CgkJICBicmVhazsKCQlkZWZhdWx0OgoJCSAgYWJvcnQgKCk7CgkJfQoJICAgIH0KCgkgIC8qIElmIHRoaXMgaXMgQSBvcCBDMSA/IEEgOiBDMiB3aXRoIEMxIGFuZCBDMiBjb25zdGFudCBpbnRlZ2VycywKCSAgICAgd2UgbWlnaHQgc3RpbGwgYmUgYWJsZSB0byBzaW1wbGlmeSB0aGlzLiAgRm9yIGV4YW1wbGUsCgkgICAgIGlmIEMxIGlzIG9uZSBsZXNzIG9yIG9uZSBtb3JlIHRoYW4gQzIsIHRoaXMgbWlnaHQgaGF2ZSBzdGFydGVkCgkgICAgIG91dCBhcyBhIE1JTiBvciBNQVggYW5kIGJlZW4gdHJhbnNmb3JtZWQgYnkgdGhpcyBmdW5jdGlvbi4KCSAgICAgT25seSBnb29kIGZvciBJTlRFR0VSX1RZUEVzLCBiZWNhdXNlIHdlIG5lZWQgVFlQRV9NQVhfVkFMVUUuICAqLwoKCSAgaWYgKElOVEVHUkFMX1RZUEVfUCAodHlwZSkKCSAgICAgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkgPT0gSU5URUdFUl9DU1QKCSAgICAgICYmIFRSRUVfQ09ERSAoYXJnMikgPT0gSU5URUdFUl9DU1QpCgkgICAgc3dpdGNoIChjb21wX2NvZGUpCgkgICAgICB7CgkgICAgICBjYXNlIEVRX0VYUFI6CgkJLyogV2UgY2FuIHJlcGxhY2UgQSB3aXRoIEMxIGluIHRoaXMgY2FzZS4gICovCgkJYXJnMSA9IGZvbGRfY29udmVydCAodHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSk7CgkJcmV0dXJuIGZvbGQgKGJ1aWxkIChjb2RlLCB0eXBlLCBUUkVFX09QRVJBTkQgKHQsIDApLCBhcmcxLAoJCQkJICAgIFRSRUVfT1BFUkFORCAodCwgMikpKTsKCgkgICAgICBjYXNlIExUX0VYUFI6CgkJLyogSWYgQzEgaXMgQzIgKyAxLCB0aGlzIGlzIG1pbihBLCBDMikuICAqLwoJCWlmICghIG9wZXJhbmRfZXF1YWxfcCAoYXJnMiwgVFlQRV9NQVhfVkFMVUUgKHR5cGUpLCAxKQoJCSAgICAmJiBvcGVyYW5kX2VxdWFsX3AgKFRSRUVfT1BFUkFORCAoYXJnMCwgMSksCgkJCQkJY29uc3RfYmlub3AgKFBMVVNfRVhQUiwgYXJnMiwKCQkJCQkJICAgICBpbnRlZ2VyX29uZV9ub2RlLCAwKSwgMSkpCgkJICByZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZQoJCSAgICAoZm9sZCAoYnVpbGQgKE1JTl9FWFBSLCB0eXBlLCBhcmcxLCBhcmcyKSkpOwoJCWJyZWFrOwoKCSAgICAgIGNhc2UgTEVfRVhQUjoKCQkvKiBJZiBDMSBpcyBDMiAtIDEsIHRoaXMgaXMgbWluKEEsIEMyKS4gICovCgkJaWYgKCEgb3BlcmFuZF9lcXVhbF9wIChhcmcyLCBUWVBFX01JTl9WQUxVRSAodHlwZSksIDEpCgkJICAgICYmIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwKCQkJCQljb25zdF9iaW5vcCAoTUlOVVNfRVhQUiwgYXJnMiwKCQkJCQkJICAgICBpbnRlZ2VyX29uZV9ub2RlLCAwKSwgMSkpCgkJICByZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZQoJCSAgICAoZm9sZCAoYnVpbGQgKE1JTl9FWFBSLCB0eXBlLCBhcmcxLCBhcmcyKSkpOwoJCWJyZWFrOwoKCSAgICAgIGNhc2UgR1RfRVhQUjoKCQkvKiBJZiBDMSBpcyBDMiAtIDEsIHRoaXMgaXMgbWF4KEEsIEMyKS4gICovCgkJaWYgKCEgb3BlcmFuZF9lcXVhbF9wIChhcmcyLCBUWVBFX01JTl9WQUxVRSAodHlwZSksIDEpCgkJICAgICYmIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwKCQkJCQljb25zdF9iaW5vcCAoTUlOVVNfRVhQUiwgYXJnMiwKCQkJCQkJICAgICBpbnRlZ2VyX29uZV9ub2RlLCAwKSwgMSkpCgkJICByZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZQoJCSAgICAoZm9sZCAoYnVpbGQgKE1BWF9FWFBSLCB0eXBlLCBhcmcxLCBhcmcyKSkpOwoJCWJyZWFrOwoKCSAgICAgIGNhc2UgR0VfRVhQUjoKCQkvKiBJZiBDMSBpcyBDMiArIDEsIHRoaXMgaXMgbWF4KEEsIEMyKS4gICovCgkJaWYgKCEgb3BlcmFuZF9lcXVhbF9wIChhcmcyLCBUWVBFX01BWF9WQUxVRSAodHlwZSksIDEpCgkJICAgICYmIG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwKCQkJCQljb25zdF9iaW5vcCAoUExVU19FWFBSLCBhcmcyLAoJCQkJCQkgICAgIGludGVnZXJfb25lX25vZGUsIDApLCAxKSkKCQkgIHJldHVybiBwZWRhbnRpY19ub25fbHZhbHVlCgkJICAgIChmb2xkIChidWlsZCAoTUFYX0VYUFIsIHR5cGUsIGFyZzEsIGFyZzIpKSk7CgkJYnJlYWs7CgkgICAgICBjYXNlIE5FX0VYUFI6CgkJYnJlYWs7CgkgICAgICBkZWZhdWx0OgoJCWFib3J0ICgpOwoJICAgICAgfQoJfQoKICAgICAgLyogSWYgdGhlIHNlY29uZCBvcGVyYW5kIGlzIHNpbXBsZXIgdGhhbiB0aGUgdGhpcmQsIHN3YXAgdGhlbQoJIHNpbmNlIHRoYXQgcHJvZHVjZXMgYmV0dGVyIGp1bXAgb3B0aW1pemF0aW9uIHJlc3VsdHMuICAqLwogICAgICBpZiAodHJlZV9zd2FwX29wZXJhbmRzX3AgKFRSRUVfT1BFUkFORCAodCwgMSksCgkJCQlUUkVFX09QRVJBTkQgKHQsIDIpLCBmYWxzZSkpCgl7CgkgIC8qIFNlZSBpZiB0aGlzIGNhbiBiZSBpbnZlcnRlZC4gIElmIGl0IGNhbid0LCBwb3NzaWJseSBiZWNhdXNlCgkgICAgIGl0IHdhcyBhIGZsb2F0aW5nLXBvaW50IGluZXF1YWxpdHkgY29tcGFyaXNvbiwgZG9uJ3QgZG8KCSAgICAgYW55dGhpbmcuICAqLwoJICB0ZW0gPSBpbnZlcnRfdHJ1dGh2YWx1ZSAoYXJnMCk7CgoJICBpZiAoVFJFRV9DT0RFICh0ZW0pICE9IFRSVVRIX05PVF9FWFBSKQoJICAgIHJldHVybiBmb2xkIChidWlsZCAoY29kZSwgdHlwZSwgdGVtLAoJCQkgVFJFRV9PUEVSQU5EICh0LCAyKSwgVFJFRV9PUEVSQU5EICh0LCAxKSkpOwoJfQoKICAgICAgLyogQ29udmVydCBBID8gMSA6IDAgdG8gc2ltcGx5IEEuICAqLwogICAgICBpZiAoaW50ZWdlcl9vbmVwIChUUkVFX09QRVJBTkQgKHQsIDEpKQoJICAmJiBpbnRlZ2VyX3plcm9wIChUUkVFX09QRVJBTkQgKHQsIDIpKQoJICAvKiBJZiB3ZSB0cnkgdG8gY29udmVydCBUUkVFX09QRVJBTkQgKHQsIDApIHRvIG91ciB0eXBlLCB0aGUKCSAgICAgY2FsbCB0byBmb2xkIHdpbGwgdHJ5IHRvIG1vdmUgdGhlIGNvbnZlcnNpb24gaW5zaWRlCgkgICAgIGEgQ09ORCwgd2hpY2ggd2lsbCByZWN1cnNlLiAgSW4gdGhhdCBjYXNlLCB0aGUgQ09ORF9FWFBSCgkgICAgIGlzIHByb2JhYmx5IHRoZSBiZXN0IGNob2ljZSwgc28gbGVhdmUgaXQgYWxvbmUuICAqLwoJICAmJiB0eXBlID09IFRSRUVfVFlQRSAoYXJnMCkpCglyZXR1cm4gcGVkYW50aWNfbm9uX2x2YWx1ZSAoYXJnMCk7CgogICAgICAvKiBDb252ZXJ0IEEgPyAwIDogMSB0byAhQS4gIFRoaXMgcHJlZmVycyB0aGUgdXNlIG9mIE5PVF9FWFBSCgkgb3ZlciBDT05EX0VYUFIgaW4gY2FzZXMgc3VjaCBhcyBmbG9hdGluZyBwb2ludCBjb21wYXJpc29ucy4gICovCiAgICAgIGlmIChpbnRlZ2VyX3plcm9wIChUUkVFX09QRVJBTkQgKHQsIDEpKQoJICAmJiBpbnRlZ2VyX29uZXAgKFRSRUVfT1BFUkFORCAodCwgMikpCgkgICYmIHRydXRoX3ZhbHVlX3AgKFRSRUVfQ09ERSAoYXJnMCkpKQoJcmV0dXJuIHBlZGFudGljX25vbl9sdmFsdWUgKGZvbGRfY29udmVydCAodHlwZSwKCQkJCQkJICBpbnZlcnRfdHJ1dGh2YWx1ZSAoYXJnMCkpKTsKCiAgICAgIC8qIExvb2sgZm9yIGV4cHJlc3Npb25zIG9mIHRoZSBmb3JtIEEgJiAyID8gMiA6IDAuICBUaGUgcmVzdWx0IG9mIHRoaXMKCSBvcGVyYXRpb24gaXMgc2ltcGx5IEEgJiAyLiAgKi8KCiAgICAgIGlmIChpbnRlZ2VyX3plcm9wIChUUkVFX09QRVJBTkQgKHQsIDIpKQoJICAmJiBUUkVFX0NPREUgKGFyZzApID09IE5FX0VYUFIKCSAgJiYgaW50ZWdlcl96ZXJvcCAoVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkKCSAgJiYgaW50ZWdlcl9wb3cycCAoYXJnMSkKCSAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGFyZzAsIDApKSA9PSBCSVRfQU5EX0VYUFIKCSAgJiYgb3BlcmFuZF9lcXVhbF9wIChUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoYXJnMCwgMCksIDEpLAoJCQkgICAgICBhcmcxLCAxKSkKCXJldHVybiBwZWRhbnRpY19ub25fbHZhbHVlIChmb2xkX2NvbnZlcnQgKHR5cGUsCgkJCQkJCSAgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSkpOwoKICAgICAgLyogQ29udmVydCBBID8gQiA6IDAgaW50byBBICYmIEIgaWYgQSBhbmQgQiBhcmUgdHJ1dGggdmFsdWVzLiAgKi8KICAgICAgaWYgKGludGVnZXJfemVyb3AgKFRSRUVfT1BFUkFORCAodCwgMikpCgkgICYmIHRydXRoX3ZhbHVlX3AgKFRSRUVfQ09ERSAoYXJnMCkpCgkgICYmIHRydXRoX3ZhbHVlX3AgKFRSRUVfQ09ERSAoYXJnMSkpKQoJcmV0dXJuIHBlZGFudGljX25vbl9sdmFsdWUgKGZvbGQgKGJ1aWxkIChUUlVUSF9BTkRJRl9FWFBSLCB0eXBlLAoJCQkJCQkgYXJnMCwgYXJnMSkpKTsKCiAgICAgIC8qIENvbnZlcnQgQSA/IEIgOiAxIGludG8gIUEgfHwgQiBpZiBBIGFuZCBCIGFyZSB0cnV0aCB2YWx1ZXMuICAqLwogICAgICBpZiAoaW50ZWdlcl9vbmVwIChUUkVFX09QRVJBTkQgKHQsIDIpKQoJICAmJiB0cnV0aF92YWx1ZV9wIChUUkVFX0NPREUgKGFyZzApKQoJICAmJiB0cnV0aF92YWx1ZV9wIChUUkVFX0NPREUgKGFyZzEpKSkKCXsKCSAgLyogT25seSBwZXJmb3JtIHRyYW5zZm9ybWF0aW9uIGlmIEFSRzAgaXMgZWFzaWx5IGludmVydGVkLiAgKi8KCSAgdGVtID0gaW52ZXJ0X3RydXRodmFsdWUgKGFyZzApOwoJICBpZiAoVFJFRV9DT0RFICh0ZW0pICE9IFRSVVRIX05PVF9FWFBSKQoJICAgIHJldHVybiBwZWRhbnRpY19ub25fbHZhbHVlIChmb2xkIChidWlsZCAoVFJVVEhfT1JJRl9FWFBSLCB0eXBlLAoJCQkJCQkgICAgIHRlbSwgYXJnMSkpKTsKCX0KCiAgICAgIHJldHVybiB0OwoKICAgIGNhc2UgQ09NUE9VTkRfRVhQUjoKICAgICAgLyogV2hlbiBwZWRhbnRpYywgYSBjb21wb3VuZCBleHByZXNzaW9uIGNhbiBiZSBuZWl0aGVyIGFuIGx2YWx1ZQoJIG5vciBhbiBpbnRlZ2VyIGNvbnN0YW50IGV4cHJlc3Npb24uICAqLwogICAgICBpZiAoVFJFRV9TSURFX0VGRkVDVFMgKGFyZzApIHx8IHBlZGFudGljKQoJcmV0dXJuIHQ7CiAgICAgIC8qIERvbid0IGxldCAoMCwgMCkgYmUgbnVsbCBwb2ludGVyIGNvbnN0YW50LiAgKi8KICAgICAgaWYgKGludGVnZXJfemVyb3AgKGFyZzEpKQoJcmV0dXJuIGJ1aWxkMSAoTk9QX0VYUFIsIHR5cGUsIGFyZzEpOwogICAgICByZXR1cm4gZm9sZF9jb252ZXJ0ICh0eXBlLCBhcmcxKTsKCiAgICBjYXNlIENPTVBMRVhfRVhQUjoKICAgICAgaWYgKHdpbnMpCglyZXR1cm4gYnVpbGRfY29tcGxleCAodHlwZSwgYXJnMCwgYXJnMSk7CiAgICAgIHJldHVybiB0OwoKICAgIGNhc2UgUkVBTFBBUlRfRVhQUjoKICAgICAgaWYgKFRSRUVfQ09ERSAoVFJFRV9UWVBFIChhcmcwKSkgIT0gQ09NUExFWF9UWVBFKQoJcmV0dXJuIHQ7CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQ09NUExFWF9FWFBSKQoJcmV0dXJuIG9taXRfb25lX29wZXJhbmQgKHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnMCwgMCksCgkJCQkgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSk7CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gQ09NUExFWF9DU1QpCglyZXR1cm4gVFJFRV9SRUFMUEFSVCAoYXJnMCk7CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoYXJnMCkgPT0gUExVU19FWFBSIHx8IFRSRUVfQ09ERSAoYXJnMCkgPT0gTUlOVVNfRVhQUikKCXJldHVybiBmb2xkIChidWlsZCAoVFJFRV9DT0RFIChhcmcwKSwgdHlwZSwKCQkJICAgIGZvbGQgKGJ1aWxkMSAoUkVBTFBBUlRfRVhQUiwgdHlwZSwKCQkJCQkgIFRSRUVfT1BFUkFORCAoYXJnMCwgMCkpKSwKCQkJICAgIGZvbGQgKGJ1aWxkMSAoUkVBTFBBUlRfRVhQUiwKCQkJCQkgIHR5cGUsIFRSRUVfT1BFUkFORCAoYXJnMCwgMSkpKSkpOwogICAgICByZXR1cm4gdDsKCiAgICBjYXNlIElNQUdQQVJUX0VYUFI6CiAgICAgIGlmIChUUkVFX0NPREUgKFRSRUVfVFlQRSAoYXJnMCkpICE9IENPTVBMRVhfVFlQRSkKCXJldHVybiBmb2xkX2NvbnZlcnQgKHR5cGUsIGludGVnZXJfemVyb19ub2RlKTsKICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBDT01QTEVYX0VYUFIpCglyZXR1cm4gb21pdF9vbmVfb3BlcmFuZCAodHlwZSwgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSwKCQkJCSBUUkVFX09QRVJBTkQgKGFyZzAsIDApKTsKICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBDT01QTEVYX0NTVCkKCXJldHVybiBUUkVFX0lNQUdQQVJUIChhcmcwKTsKICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFIChhcmcwKSA9PSBQTFVTX0VYUFIgfHwgVFJFRV9DT0RFIChhcmcwKSA9PSBNSU5VU19FWFBSKQoJcmV0dXJuIGZvbGQgKGJ1aWxkIChUUkVFX0NPREUgKGFyZzApLCB0eXBlLAoJCQkgICAgZm9sZCAoYnVpbGQxIChJTUFHUEFSVF9FWFBSLCB0eXBlLAoJCQkJCSAgVFJFRV9PUEVSQU5EIChhcmcwLCAwKSkpLAoJCQkgICAgZm9sZCAoYnVpbGQxIChJTUFHUEFSVF9FWFBSLCB0eXBlLAoJCQkJCSAgVFJFRV9PUEVSQU5EIChhcmcwLCAxKSkpKSk7CiAgICAgIHJldHVybiB0OwoKICAgICAgLyogUHVsbCBhcml0aG1ldGljIG9wcyBvdXQgb2YgdGhlIENMRUFOVVBfUE9JTlRfRVhQUiB3aGVyZQogICAgICAgICBhcHByb3ByaWF0ZS4gICovCiAgICBjYXNlIENMRUFOVVBfUE9JTlRfRVhQUjoKICAgICAgaWYgKCEgaGFzX2NsZWFudXBzIChhcmcwKSkKCXJldHVybiBUUkVFX09QRVJBTkQgKHQsIDApOwoKICAgICAgewoJZW51bSB0cmVlX2NvZGUgY29kZTAgPSBUUkVFX0NPREUgKGFyZzApOwoJaW50IGtpbmQwID0gVFJFRV9DT0RFX0NMQVNTIChjb2RlMCk7Cgl0cmVlIGFyZzAwID0gVFJFRV9PUEVSQU5EIChhcmcwLCAwKTsKCXRyZWUgYXJnMDE7CgoJaWYgKGtpbmQwID09ICcxJyB8fCBjb2RlMCA9PSBUUlVUSF9OT1RfRVhQUikKCSAgcmV0dXJuIGZvbGQgKGJ1aWxkMSAoY29kZTAsIHR5cGUsCgkJCSAgICAgICBmb2xkIChidWlsZDEgKENMRUFOVVBfUE9JTlRfRVhQUiwKCQkJCQkgICAgIFRSRUVfVFlQRSAoYXJnMDApLCBhcmcwMCkpKSk7CgoJaWYgKGtpbmQwID09ICc8JyB8fCBraW5kMCA9PSAnMicKCSAgICB8fCBjb2RlMCA9PSBUUlVUSF9BTkRJRl9FWFBSIHx8IGNvZGUwID09IFRSVVRIX09SSUZfRVhQUgoJICAgIHx8IGNvZGUwID09IFRSVVRIX0FORF9FWFBSICAgfHwgY29kZTAgPT0gVFJVVEhfT1JfRVhQUgoJICAgIHx8IGNvZGUwID09IFRSVVRIX1hPUl9FWFBSKQoJICB7CgkgICAgYXJnMDEgPSBUUkVFX09QRVJBTkQgKGFyZzAsIDEpOwoKCSAgICBpZiAoVFJFRV9DT05TVEFOVCAoYXJnMDApCgkJfHwgKChjb2RlMCA9PSBUUlVUSF9BTkRJRl9FWFBSIHx8IGNvZGUwID09IFRSVVRIX09SSUZfRVhQUikKCQkgICAgJiYgISBoYXNfY2xlYW51cHMgKGFyZzAwKSkpCgkgICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUwLCB0eXBlLCBhcmcwMCwKCQkJCSAgZm9sZCAoYnVpbGQxIChDTEVBTlVQX1BPSU5UX0VYUFIsCgkJCQkJCVRSRUVfVFlQRSAoYXJnMDEpLCBhcmcwMSkpKSk7CgoJICAgIGlmIChUUkVFX0NPTlNUQU5UIChhcmcwMSkpCgkgICAgICByZXR1cm4gZm9sZCAoYnVpbGQgKGNvZGUwLCB0eXBlLAoJCQkJICBmb2xkIChidWlsZDEgKENMRUFOVVBfUE9JTlRfRVhQUiwKCQkJCQkJVFJFRV9UWVBFIChhcmcwMCksIGFyZzAwKSksCgkJCQkgIGFyZzAxKSk7CgkgIH0KCglyZXR1cm4gdDsKICAgICAgfQoKICAgIGNhc2UgQ0FMTF9FWFBSOgogICAgICAvKiBDaGVjayBmb3IgYSBidWlsdC1pbiBmdW5jdGlvbi4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAoZXhwciwgMCkpID09IEFERFJfRVhQUgoJICAmJiAoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoZXhwciwgMCksIDApKQoJICAgICAgPT0gRlVOQ1RJT05fREVDTCkKCSAgJiYgREVDTF9CVUlMVF9JTiAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKGV4cHIsIDApLCAwKSkpCgl7CgkgIHRyZWUgdG1wID0gZm9sZF9idWlsdGluIChleHByKTsKCSAgaWYgKHRtcCkKCSAgICByZXR1cm4gdG1wOwoJfQogICAgICByZXR1cm4gdDsKCiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gdDsKICAgIH0gLyogc3dpdGNoIChjb2RlKSAqLwp9CgojaWZkZWYgRU5BQkxFX0ZPTERfQ0hFQ0tJTkcKI3VuZGVmIGZvbGQKCnN0YXRpYyB2b2lkIGZvbGRfY2hlY2tzdW1fdHJlZSAodHJlZSwgc3RydWN0IG1kNV9jdHggKiwgaHRhYl90KTsKc3RhdGljIHZvaWQgZm9sZF9jaGVja19mYWlsZWQgKHRyZWUsIHRyZWUpOwp2b2lkIHByaW50X2ZvbGRfY2hlY2tzdW0gKHRyZWUpOwoKLyogV2hlbiAtLWVuYWJsZS1jaGVja2luZz1mb2xkLCBjb21wdXRlIGEgZGlnZXN0IG9mIGV4cHIgYmVmb3JlCiAgIGFuZCBhZnRlciBhY3R1YWwgZm9sZCBjYWxsIHRvIHNlZSBpZiBmb2xkIGRpZCBub3QgYWNjaWRlbnRhbGx5CiAgIGNoYW5nZSBvcmlnaW5hbCBleHByLiAgKi8KCnRyZWUKZm9sZCAodHJlZSBleHByKQp7CiAgdHJlZSByZXQ7CiAgc3RydWN0IG1kNV9jdHggY3R4OwogIHVuc2lnbmVkIGNoYXIgY2hlY2tzdW1fYmVmb3JlWzE2XSwgY2hlY2tzdW1fYWZ0ZXJbMTZdOwogIGh0YWJfdCBodDsKCiAgaHQgPSBodGFiX2NyZWF0ZSAoMzIsIGh0YWJfaGFzaF9wb2ludGVyLCBodGFiX2VxX3BvaW50ZXIsIE5VTEwpOwogIG1kNV9pbml0X2N0eCAoJmN0eCk7CiAgZm9sZF9jaGVja3N1bV90cmVlIChleHByLCAmY3R4LCBodCk7CiAgbWQ1X2ZpbmlzaF9jdHggKCZjdHgsIGNoZWNrc3VtX2JlZm9yZSk7CiAgaHRhYl9lbXB0eSAoaHQpOwoKICByZXQgPSBmb2xkXzEgKGV4cHIpOwoKICBtZDVfaW5pdF9jdHggKCZjdHgpOwogIGZvbGRfY2hlY2tzdW1fdHJlZSAoZXhwciwgJmN0eCwgaHQpOwogIG1kNV9maW5pc2hfY3R4ICgmY3R4LCBjaGVja3N1bV9hZnRlcik7CiAgaHRhYl9kZWxldGUgKGh0KTsKCiAgaWYgKG1lbWNtcCAoY2hlY2tzdW1fYmVmb3JlLCBjaGVja3N1bV9hZnRlciwgMTYpKQogICAgZm9sZF9jaGVja19mYWlsZWQgKGV4cHIsIHJldCk7CgogIHJldHVybiByZXQ7Cn0KCnZvaWQKcHJpbnRfZm9sZF9jaGVja3N1bSAodHJlZSBleHByKQp7CiAgc3RydWN0IG1kNV9jdHggY3R4OwogIHVuc2lnbmVkIGNoYXIgY2hlY2tzdW1bMTZdLCBjbnQ7CiAgaHRhYl90IGh0OwoKICBodCA9IGh0YWJfY3JlYXRlICgzMiwgaHRhYl9oYXNoX3BvaW50ZXIsIGh0YWJfZXFfcG9pbnRlciwgTlVMTCk7CiAgbWQ1X2luaXRfY3R4ICgmY3R4KTsKICBmb2xkX2NoZWNrc3VtX3RyZWUgKGV4cHIsICZjdHgsIGh0KTsKICBtZDVfZmluaXNoX2N0eCAoJmN0eCwgY2hlY2tzdW0pOwogIGh0YWJfZGVsZXRlIChodCk7CiAgZm9yIChjbnQgPSAwOyBjbnQgPCAxNjsgKytjbnQpCiAgICBmcHJpbnRmIChzdGRlcnIsICIlMDJ4IiwgY2hlY2tzdW1bY250XSk7CiAgcHV0YyAoJ1xuJywgc3RkZXJyKTsKfQoKc3RhdGljIHZvaWQKZm9sZF9jaGVja19mYWlsZWQgKHRyZWUgZXhwciBBVFRSSUJVVEVfVU5VU0VELCB0cmVlIHJldCBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgaW50ZXJuYWxfZXJyb3IgKCJmb2xkIGNoZWNrOiBvcmlnaW5hbCB0cmVlIGNoYW5nZWQgYnkgZm9sZCIpOwp9CgpzdGF0aWMgdm9pZApmb2xkX2NoZWNrc3VtX3RyZWUgKHRyZWUgZXhwciwgc3RydWN0IG1kNV9jdHggKmN0eCwgaHRhYl90IGh0KQp7CiAgdm9pZCAqKnNsb3Q7CiAgZW51bSB0cmVlX2NvZGUgY29kZTsKICBjaGFyIGJ1ZltzaXplb2YgKHN0cnVjdCB0cmVlX2RlY2wpXTsKICBpbnQgaSwgbGVuOwoKICBpZiAoc2l6ZW9mIChzdHJ1Y3QgdHJlZV9leHApICsgNSAqIHNpemVvZiAodHJlZSkKICAgICAgPiBzaXplb2YgKHN0cnVjdCB0cmVlX2RlY2wpCiAgICAgIHx8IHNpemVvZiAoc3RydWN0IHRyZWVfdHlwZSkgPiBzaXplb2YgKHN0cnVjdCB0cmVlX2RlY2wpKQogICAgYWJvcnQgKCk7CiAgaWYgKGV4cHIgPT0gTlVMTCkKICAgIHJldHVybjsKICBzbG90ID0gaHRhYl9maW5kX3Nsb3QgKGh0LCBleHByLCBJTlNFUlQpOwogIGlmICgqc2xvdCAhPSBOVUxMKQogICAgcmV0dXJuOwogICpzbG90ID0gZXhwcjsKICBjb2RlID0gVFJFRV9DT0RFIChleHByKTsKICBpZiAoY29kZSA9PSBTQVZFX0VYUFIgJiYgU0FWRV9FWFBSX05PUExBQ0VIT0xERVIgKGV4cHIpKQogICAgewogICAgICAvKiBBbGxvdyBTQVZFX0VYUFJfTk9QTEFDRUhPTERFUiBmbGFnIHRvIGJlIG1vZGlmaWVkLiAgKi8KICAgICAgbWVtY3B5IChidWYsIGV4cHIsIHRyZWVfc2l6ZSAoZXhwcikpOwogICAgICBleHByID0gKHRyZWUpIGJ1ZjsKICAgICAgU0FWRV9FWFBSX05PUExBQ0VIT0xERVIgKGV4cHIpID0gMDsKICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREVfQ0xBU1MgKGNvZGUpID09ICdkJyAmJiBERUNMX0FTU0VNQkxFUl9OQU1FX1NFVF9QIChleHByKSkKICAgIHsKICAgICAgLyogQWxsb3cgREVDTF9BU1NFTUJMRVJfTkFNRSB0byBiZSBtb2RpZmllZC4gICovCiAgICAgIG1lbWNweSAoYnVmLCBleHByLCB0cmVlX3NpemUgKGV4cHIpKTsKICAgICAgZXhwciA9ICh0cmVlKSBidWY7CiAgICAgIFNFVF9ERUNMX0FTU0VNQkxFUl9OQU1FIChleHByLCBOVUxMKTsKICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREVfQ0xBU1MgKGNvZGUpID09ICd0JwoJICAgJiYgKFRZUEVfUE9JTlRFUl9UTyAoZXhwcikgfHwgVFlQRV9SRUZFUkVOQ0VfVE8gKGV4cHIpKSkKICAgIHsKICAgICAgLyogQWxsb3cgVFlQRV9QT0lOVEVSX1RPIGFuZCBUWVBFX1JFRkVSRU5DRV9UTyB0byBiZSBtb2RpZmllZC4gICovCiAgICAgIG1lbWNweSAoYnVmLCBleHByLCB0cmVlX3NpemUgKGV4cHIpKTsKICAgICAgZXhwciA9ICh0cmVlKSBidWY7CiAgICAgIFRZUEVfUE9JTlRFUl9UTyAoZXhwcikgPSBOVUxMOwogICAgICBUWVBFX1JFRkVSRU5DRV9UTyAoZXhwcikgPSBOVUxMOwogICAgfQogIG1kNV9wcm9jZXNzX2J5dGVzIChleHByLCB0cmVlX3NpemUgKGV4cHIpLCBjdHgpOwogIGZvbGRfY2hlY2tzdW1fdHJlZSAoVFJFRV9UWVBFIChleHByKSwgY3R4LCBodCk7CiAgaWYgKFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgIT0gJ3QnICYmIFRSRUVfQ09ERV9DTEFTUyAoY29kZSkgIT0gJ2QnKQogICAgZm9sZF9jaGVja3N1bV90cmVlIChUUkVFX0NIQUlOIChleHByKSwgY3R4LCBodCk7CiAgbGVuID0gVFJFRV9DT0RFX0xFTkdUSCAoY29kZSk7CiAgc3dpdGNoIChUUkVFX0NPREVfQ0xBU1MgKGNvZGUpKQogICAgewogICAgY2FzZSAnYyc6CiAgICAgIHN3aXRjaCAoY29kZSkKCXsKCWNhc2UgU1RSSU5HX0NTVDoKCSAgbWQ1X3Byb2Nlc3NfYnl0ZXMgKFRSRUVfU1RSSU5HX1BPSU5URVIgKGV4cHIpLAoJCQkgICAgIFRSRUVfU1RSSU5HX0xFTkdUSCAoZXhwciksIGN0eCk7CgkgIGJyZWFrOwoJY2FzZSBDT01QTEVYX0NTVDoKCSAgZm9sZF9jaGVja3N1bV90cmVlIChUUkVFX1JFQUxQQVJUIChleHByKSwgY3R4LCBodCk7CgkgIGZvbGRfY2hlY2tzdW1fdHJlZSAoVFJFRV9JTUFHUEFSVCAoZXhwciksIGN0eCwgaHQpOwoJICBicmVhazsKCWNhc2UgVkVDVE9SX0NTVDoKCSAgZm9sZF9jaGVja3N1bV90cmVlIChUUkVFX1ZFQ1RPUl9DU1RfRUxUUyAoZXhwciksIGN0eCwgaHQpOwoJICBicmVhazsKCWRlZmF1bHQ6CgkgIGJyZWFrOwoJfQogICAgICBicmVhazsKICAgIGNhc2UgJ3gnOgogICAgICBzd2l0Y2ggKGNvZGUpCgl7CgljYXNlIFRSRUVfTElTVDoKCSAgZm9sZF9jaGVja3N1bV90cmVlIChUUkVFX1BVUlBPU0UgKGV4cHIpLCBjdHgsIGh0KTsKCSAgZm9sZF9jaGVja3N1bV90cmVlIChUUkVFX1ZBTFVFIChleHByKSwgY3R4LCBodCk7CgkgIGJyZWFrOwoJY2FzZSBUUkVFX1ZFQzoKCSAgZm9yIChpID0gMDsgaSA8IFRSRUVfVkVDX0xFTkdUSCAoZXhwcik7ICsraSkKCSAgICBmb2xkX2NoZWNrc3VtX3RyZWUgKFRSRUVfVkVDX0VMVCAoZXhwciwgaSksIGN0eCwgaHQpOwoJICBicmVhazsKCWRlZmF1bHQ6CgkgIGJyZWFrOwoJfQogICAgICBicmVhazsKICAgIGNhc2UgJ2UnOgogICAgICBzd2l0Y2ggKGNvZGUpCgl7CgljYXNlIFNBVkVfRVhQUjogbGVuID0gMjsgYnJlYWs7CgljYXNlIEdPVE9fU1VCUk9VVElORV9FWFBSOiBsZW4gPSAwOyBicmVhazsKCWNhc2UgUlRMX0VYUFI6IGxlbiA9IDA7IGJyZWFrOwoJY2FzZSBXSVRIX0NMRUFOVVBfRVhQUjogbGVuID0gMjsgYnJlYWs7CglkZWZhdWx0OiBicmVhazsKCX0KICAgICAgLyogRmFsbCB0aHJvdWdoLiAgKi8KICAgIGNhc2UgJ3InOgogICAgY2FzZSAnPCc6CiAgICBjYXNlICcxJzoKICAgIGNhc2UgJzInOgogICAgY2FzZSAncyc6CiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47ICsraSkKCWZvbGRfY2hlY2tzdW1fdHJlZSAoVFJFRV9PUEVSQU5EIChleHByLCBpKSwgY3R4LCBodCk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnZCc6CiAgICAgIGZvbGRfY2hlY2tzdW1fdHJlZSAoREVDTF9TSVpFIChleHByKSwgY3R4LCBodCk7CiAgICAgIGZvbGRfY2hlY2tzdW1fdHJlZSAoREVDTF9TSVpFX1VOSVQgKGV4cHIpLCBjdHgsIGh0KTsKICAgICAgZm9sZF9jaGVja3N1bV90cmVlIChERUNMX05BTUUgKGV4cHIpLCBjdHgsIGh0KTsKICAgICAgZm9sZF9jaGVja3N1bV90cmVlIChERUNMX0NPTlRFWFQgKGV4cHIpLCBjdHgsIGh0KTsKICAgICAgZm9sZF9jaGVja3N1bV90cmVlIChERUNMX0FSR1VNRU5UUyAoZXhwciksIGN0eCwgaHQpOwogICAgICBmb2xkX2NoZWNrc3VtX3RyZWUgKERFQ0xfUkVTVUxUX0ZMRCAoZXhwciksIGN0eCwgaHQpOwogICAgICBmb2xkX2NoZWNrc3VtX3RyZWUgKERFQ0xfSU5JVElBTCAoZXhwciksIGN0eCwgaHQpOwogICAgICBmb2xkX2NoZWNrc3VtX3RyZWUgKERFQ0xfQUJTVFJBQ1RfT1JJR0lOIChleHByKSwgY3R4LCBodCk7CiAgICAgIGZvbGRfY2hlY2tzdW1fdHJlZSAoREVDTF9TRUNUSU9OX05BTUUgKGV4cHIpLCBjdHgsIGh0KTsKICAgICAgZm9sZF9jaGVja3N1bV90cmVlIChERUNMX0FUVFJJQlVURVMgKGV4cHIpLCBjdHgsIGh0KTsKICAgICAgZm9sZF9jaGVja3N1bV90cmVlIChERUNMX1ZJTkRFWCAoZXhwciksIGN0eCwgaHQpOwogICAgICBicmVhazsKICAgIGNhc2UgJ3QnOgogICAgICBmb2xkX2NoZWNrc3VtX3RyZWUgKFRZUEVfVkFMVUVTIChleHByKSwgY3R4LCBodCk7CiAgICAgIGZvbGRfY2hlY2tzdW1fdHJlZSAoVFlQRV9TSVpFIChleHByKSwgY3R4LCBodCk7CiAgICAgIGZvbGRfY2hlY2tzdW1fdHJlZSAoVFlQRV9TSVpFX1VOSVQgKGV4cHIpLCBjdHgsIGh0KTsKICAgICAgZm9sZF9jaGVja3N1bV90cmVlIChUWVBFX0FUVFJJQlVURVMgKGV4cHIpLCBjdHgsIGh0KTsKICAgICAgZm9sZF9jaGVja3N1bV90cmVlIChUWVBFX05BTUUgKGV4cHIpLCBjdHgsIGh0KTsKICAgICAgZm9sZF9jaGVja3N1bV90cmVlIChUWVBFX01JTl9WQUxVRSAoZXhwciksIGN0eCwgaHQpOwogICAgICBmb2xkX2NoZWNrc3VtX3RyZWUgKFRZUEVfTUFYX1ZBTFVFIChleHByKSwgY3R4LCBodCk7CiAgICAgIGZvbGRfY2hlY2tzdW1fdHJlZSAoVFlQRV9NQUlOX1ZBUklBTlQgKGV4cHIpLCBjdHgsIGh0KTsKICAgICAgZm9sZF9jaGVja3N1bV90cmVlIChUWVBFX0JJTkZPIChleHByKSwgY3R4LCBodCk7CiAgICAgIGZvbGRfY2hlY2tzdW1fdHJlZSAoVFlQRV9DT05URVhUIChleHByKSwgY3R4LCBodCk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgICB9Cn0KCiNlbmRpZgoKLyogUGVyZm9ybSBjb25zdGFudCBmb2xkaW5nIGFuZCByZWxhdGVkIHNpbXBsaWZpY2F0aW9uIG9mIGluaXRpYWxpemVyCiAgIGV4cHJlc3Npb24gRVhQUi4gIFRoaXMgYmVoYXZlcyBpZGVudGljYWxseSB0byAiZm9sZCIgYnV0IGlnbm9yZXMKICAgcG90ZW50aWFsIHJ1bi10aW1lIHRyYXBzIGFuZCBleGNlcHRpb25zIHRoYXQgZm9sZCBtdXN0IHByZXNlcnZlLiAgKi8KCnRyZWUKZm9sZF9pbml0aWFsaXplciAodHJlZSBleHByKQp7CiAgaW50IHNhdmVkX3NpZ25hbGluZ19uYW5zID0gZmxhZ19zaWduYWxpbmdfbmFuczsKICBpbnQgc2F2ZWRfdHJhcHBpbmdfbWF0aCA9IGZsYWdfdHJhcHBpbmdfbWF0aDsKICBpbnQgc2F2ZWRfdHJhcHYgPSBmbGFnX3RyYXB2OwogIHRyZWUgcmVzdWx0OwoKICBmbGFnX3NpZ25hbGluZ19uYW5zID0gMDsKICBmbGFnX3RyYXBwaW5nX21hdGggPSAwOwogIGZsYWdfdHJhcHYgPSAwOwoKICByZXN1bHQgPSBmb2xkIChleHByKTsKCiAgZmxhZ19zaWduYWxpbmdfbmFucyA9IHNhdmVkX3NpZ25hbGluZ19uYW5zOwogIGZsYWdfdHJhcHBpbmdfbWF0aCA9IHNhdmVkX3RyYXBwaW5nX21hdGg7CiAgZmxhZ190cmFwdiA9IHNhdmVkX3RyYXB2OwoKICByZXR1cm4gcmVzdWx0Owp9CgovKiBEZXRlcm1pbmUgaWYgZmlyc3QgYXJndW1lbnQgaXMgYSBtdWx0aXBsZSBvZiBzZWNvbmQgYXJndW1lbnQuICBSZXR1cm4gMCBpZgogICBpdCBpcyBub3QsIG9yIHdlIGNhbm5vdCBlYXNpbHkgZGV0ZXJtaW5lZCBpdCB0byBiZS4KCiAgIEFuIGV4YW1wbGUgb2YgdGhlIHNvcnQgb2YgdGhpbmcgd2UgY2FyZSBhYm91dCAoYXQgdGhpcyBwb2ludDsgdGhpcyByb3V0aW5lCiAgIGNvdWxkIHN1cmVseSBiZSBtYWRlIG1vcmUgZ2VuZXJhbCwgYW5kIGV4cGFuZGVkIHRvIGRvIHdoYXQgdGhlICpfRElWX0VYUFIncwogICBmb2xkIGNhc2VzIGRvIG5vdykgaXMgZGlzY292ZXJpbmcgdGhhdAoKICAgICBTQVZFX0VYUFIgKEkpICogU0FWRV9FWFBSIChKICogOCkKCiAgIGlzIGEgbXVsdGlwbGUgb2YKCiAgICAgU0FWRV9FWFBSIChKICogOCkKCiAgIHdoZW4gd2Uga25vdyB0aGF0IHRoZSB0d28gU0FWRV9FWFBSIChKICogOCkgbm9kZXMgYXJlIHRoZSBzYW1lIG5vZGUuCgogICBUaGlzIGNvZGUgYWxzbyBoYW5kbGVzIGRpc2NvdmVyaW5nIHRoYXQKCiAgICAgU0FWRV9FWFBSIChJKSAqIFNBVkVfRVhQUiAoSiAqIDgpCgogICBpcyBhIG11bHRpcGxlIG9mIDggc28gd2UgZG9uJ3QgaGF2ZSB0byB3b3JyeSBhYm91dCBkZWFsaW5nIHdpdGggYQogICBwb3NzaWJsZSByZW1haW5kZXIuCgogICBOb3RlIHRoYXQgd2UgKmxvb2sqIGluc2lkZSBhIFNBVkVfRVhQUiBvbmx5IHRvIGRldGVybWluZSBob3cgaXQgd2FzCiAgIGNhbGN1bGF0ZWQ7IGl0IGlzIG5vdCBzYWZlIGZvciBmb2xkIHRvIGRvIG11Y2ggb2YgYW55dGhpbmcgZWxzZSB3aXRoIHRoZQogICBpbnRlcm5hbHMgb2YgYSBTQVZFX0VYUFIsIHNpbmNlIGl0IGNhbm5vdCBrbm93IHdoZW4gaXQgd2lsbCBiZSBldmFsdWF0ZWQKICAgYXQgcnVuIHRpbWUuICBGb3IgZXhhbXBsZSwgdGhlIGxhdHRlciBleGFtcGxlIGFib3ZlICpjYW5ub3QqIGJlIGltcGxlbWVudGVkCiAgIGFzIFNBVkVfRVhQUiAoSSkgKiBKIG9yIGFueSB2YXJpYW50IHRoZXJlb2YsIHNpbmNlIHRoZSB2YWx1ZSBvZiBKIGF0CiAgIGV2YWx1YXRpb24gdGltZSBvZiB0aGUgb3JpZ2luYWwgU0FWRV9FWFBSIGlzIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBhdAogICB0aGUgdGltZSB0aGUgbmV3IGV4cHJlc3Npb24gaXMgZXZhbHVhdGVkLiAgVGhlIG9ubHkgb3B0aW1pemF0aW9uIG9mIHRoaXMKICAgc29ydCB0aGF0IHdvdWxkIGJlIHZhbGlkIGlzIGNoYW5naW5nCgogICAgIFNBVkVfRVhQUiAoSSkgKiBTQVZFX0VYUFIgKFNBVkVfRVhQUiAoSikgKiA4KQoKICAgZGl2aWRlZCBieSA4IHRvCgogICAgIFNBVkVfRVhQUiAoSSkgKiBTQVZFX0VYUFIgKEopCgogICAod2hlcmUgdGhlIHNhbWUgU0FWRV9FWFBSIChKKSBpcyB1c2VkIGluIHRoZSBvcmlnaW5hbCBhbmQgdGhlCiAgIHRyYW5zZm9ybWVkIHZlcnNpb24pLiAgKi8KCnN0YXRpYyBpbnQKbXVsdGlwbGVfb2ZfcCAodHJlZSB0eXBlLCB0cmVlIHRvcCwgdHJlZSBib3R0b20pCnsKICBpZiAob3BlcmFuZF9lcXVhbF9wICh0b3AsIGJvdHRvbSwgMCkpCiAgICByZXR1cm4gMTsKCiAgaWYgKFRSRUVfQ09ERSAodHlwZSkgIT0gSU5URUdFUl9UWVBFKQogICAgcmV0dXJuIDA7CgogIHN3aXRjaCAoVFJFRV9DT0RFICh0b3ApKQogICAgewogICAgY2FzZSBNVUxUX0VYUFI6CiAgICAgIHJldHVybiAobXVsdGlwbGVfb2ZfcCAodHlwZSwgVFJFRV9PUEVSQU5EICh0b3AsIDApLCBib3R0b20pCgkgICAgICB8fCBtdWx0aXBsZV9vZl9wICh0eXBlLCBUUkVFX09QRVJBTkQgKHRvcCwgMSksIGJvdHRvbSkpOwoKICAgIGNhc2UgUExVU19FWFBSOgogICAgY2FzZSBNSU5VU19FWFBSOgogICAgICByZXR1cm4gKG11bHRpcGxlX29mX3AgKHR5cGUsIFRSRUVfT1BFUkFORCAodG9wLCAwKSwgYm90dG9tKQoJICAgICAgJiYgbXVsdGlwbGVfb2ZfcCAodHlwZSwgVFJFRV9PUEVSQU5EICh0b3AsIDEpLCBib3R0b20pKTsKCiAgICBjYXNlIExTSElGVF9FWFBSOgogICAgICBpZiAoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHRvcCwgMSkpID09IElOVEVHRVJfQ1NUKQoJewoJICB0cmVlIG9wMSwgdDE7CgoJICBvcDEgPSBUUkVFX09QRVJBTkQgKHRvcCwgMSk7CgkgIC8qIGNvbnN0X2Jpbm9wIG1heSBub3QgZGV0ZWN0IG92ZXJmbG93IGNvcnJlY3RseSwKCSAgICAgc28gY2hlY2sgZm9yIGl0IGV4cGxpY2l0bHkgaGVyZS4gICovCgkgIGlmIChUWVBFX1BSRUNJU0lPTiAoVFJFRV9UWVBFIChzaXplX29uZV9ub2RlKSkKCSAgICAgID4gVFJFRV9JTlRfQ1NUX0xPVyAob3AxKQoJICAgICAgJiYgVFJFRV9JTlRfQ1NUX0hJR0ggKG9wMSkgPT0gMAoJICAgICAgJiYgMCAhPSAodDEgPSBmb2xkX2NvbnZlcnQgKHR5cGUsCgkJCQkJICBjb25zdF9iaW5vcCAoTFNISUZUX0VYUFIsCgkJCQkJCSAgICAgICBzaXplX29uZV9ub2RlLAoJCQkJCQkgICAgICAgb3AxLCAwKSkpCgkgICAgICAmJiAhIFRSRUVfT1ZFUkZMT1cgKHQxKSkKCSAgICByZXR1cm4gbXVsdGlwbGVfb2ZfcCAodHlwZSwgdDEsIGJvdHRvbSk7Cgl9CiAgICAgIHJldHVybiAwOwoKICAgIGNhc2UgTk9QX0VYUFI6CiAgICAgIC8qIENhbid0IGhhbmRsZSBjb252ZXJzaW9ucyBmcm9tIG5vbi1pbnRlZ3JhbCBvciB3aWRlciBpbnRlZ3JhbCB0eXBlLiAgKi8KICAgICAgaWYgKChUUkVFX0NPREUgKFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EICh0b3AsIDApKSkgIT0gSU5URUdFUl9UWVBFKQoJICB8fCAoVFlQRV9QUkVDSVNJT04gKHR5cGUpCgkgICAgICA8IFRZUEVfUFJFQ0lTSU9OIChUUkVFX1RZUEUgKFRSRUVfT1BFUkFORCAodG9wLCAwKSkpKSkKCXJldHVybiAwOwoKICAgICAgLyogLi4gZmFsbCB0aHJvdWdoIC4uLiAgKi8KCiAgICBjYXNlIFNBVkVfRVhQUjoKICAgICAgcmV0dXJuIG11bHRpcGxlX29mX3AgKHR5cGUsIFRSRUVfT1BFUkFORCAodG9wLCAwKSwgYm90dG9tKTsKCiAgICBjYXNlIElOVEVHRVJfQ1NUOgogICAgICBpZiAoVFJFRV9DT0RFIChib3R0b20pICE9IElOVEVHRVJfQ1NUCgkgIHx8IChUUkVFX1VOU0lHTkVEICh0eXBlKQoJICAgICAgJiYgKHRyZWVfaW50X2NzdF9zZ24gKHRvcCkgPCAwCgkJICB8fCB0cmVlX2ludF9jc3Rfc2duIChib3R0b20pIDwgMCkpKQoJcmV0dXJuIDA7CiAgICAgIHJldHVybiBpbnRlZ2VyX3plcm9wIChjb25zdF9iaW5vcCAoVFJVTkNfTU9EX0VYUFIsCgkJCQkJIHRvcCwgYm90dG9tLCAwKSk7CgogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KCi8qIFJldHVybiB0cnVlIGlmIGB0JyBpcyBrbm93biB0byBiZSBub24tbmVnYXRpdmUuICAqLwoKaW50CnRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wICh0cmVlIHQpCnsKICBzd2l0Y2ggKFRSRUVfQ09ERSAodCkpCiAgICB7CiAgICBjYXNlIEFCU19FWFBSOgogICAgICByZXR1cm4gMTsKCiAgICBjYXNlIElOVEVHRVJfQ1NUOgogICAgICByZXR1cm4gdHJlZV9pbnRfY3N0X3NnbiAodCkgPj0gMDsKCiAgICBjYXNlIFJFQUxfQ1NUOgogICAgICByZXR1cm4gISBSRUFMX1ZBTFVFX05FR0FUSVZFIChUUkVFX1JFQUxfQ1NUICh0KSk7CgogICAgY2FzZSBQTFVTX0VYUFI6CiAgICAgIGlmIChGTE9BVF9UWVBFX1AgKFRSRUVfVFlQRSAodCkpKQoJcmV0dXJuIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDApKQoJICAgICAgICYmIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDEpKTsKCiAgICAgIC8qIHplcm9fZXh0ZW5kKHgpICsgemVyb19leHRlbmQoeSkgaXMgbm9uLW5lZ2F0aXZlIGlmIHggYW5kIHkgYXJlCgkgYm90aCB1bnNpZ25lZCBhbmQgYXQgbGVhc3QgMiBiaXRzIHNob3J0ZXIgdGhhbiB0aGUgcmVzdWx0LiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoVFJFRV9UWVBFICh0KSkgPT0gSU5URUdFUl9UWVBFCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EICh0LCAwKSkgPT0gTk9QX0VYUFIKCSAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHQsIDEpKSA9PSBOT1BfRVhQUikKCXsKCSAgdHJlZSBpbm5lcjEgPSBUUkVFX1RZUEUgKFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh0LCAwKSwgMCkpOwoJICB0cmVlIGlubmVyMiA9IFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDEpLCAwKSk7CgkgIGlmIChUUkVFX0NPREUgKGlubmVyMSkgPT0gSU5URUdFUl9UWVBFICYmIFRSRUVfVU5TSUdORUQgKGlubmVyMSkKCSAgICAgICYmIFRSRUVfQ09ERSAoaW5uZXIyKSA9PSBJTlRFR0VSX1RZUEUgJiYgVFJFRV9VTlNJR05FRCAoaW5uZXIyKSkKCSAgICB7CgkgICAgICB1bnNpZ25lZCBpbnQgcHJlYyA9IE1BWCAoVFlQRV9QUkVDSVNJT04gKGlubmVyMSksCgkJCQkgICAgICAgVFlQRV9QUkVDSVNJT04gKGlubmVyMikpICsgMTsKCSAgICAgIHJldHVybiBwcmVjIDwgVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAodCkpOwoJICAgIH0KCX0KICAgICAgYnJlYWs7CgogICAgY2FzZSBNVUxUX0VYUFI6CiAgICAgIGlmIChGTE9BVF9UWVBFX1AgKFRSRUVfVFlQRSAodCkpKQoJewoJICAvKiB4ICogeCBmb3IgZmxvYXRpbmcgcG9pbnQgeCBpcyBhbHdheXMgbm9uLW5lZ2F0aXZlLiAgKi8KCSAgaWYgKG9wZXJhbmRfZXF1YWxfcCAoVFJFRV9PUEVSQU5EICh0LCAwKSwgVFJFRV9PUEVSQU5EICh0LCAxKSwgMCkpCgkgICAgcmV0dXJuIDE7CgkgIHJldHVybiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9PUEVSQU5EICh0LCAwKSkKCQkgJiYgdHJlZV9leHByX25vbm5lZ2F0aXZlX3AgKFRSRUVfT1BFUkFORCAodCwgMSkpOwoJfQoKICAgICAgLyogemVyb19leHRlbmQoeCkgKiB6ZXJvX2V4dGVuZCh5KSBpcyBub24tbmVnYXRpdmUgaWYgeCBhbmQgeSBhcmUKCSBib3RoIHVuc2lnbmVkIGFuZCB0aGVpciB0b3RhbCBiaXRzIGlzIHNob3J0ZXIgdGhhbiB0aGUgcmVzdWx0LiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAoVFJFRV9UWVBFICh0KSkgPT0gSU5URUdFUl9UWVBFCgkgICYmIFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EICh0LCAwKSkgPT0gTk9QX0VYUFIKCSAgJiYgVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKHQsIDEpKSA9PSBOT1BfRVhQUikKCXsKCSAgdHJlZSBpbm5lcjEgPSBUUkVFX1RZUEUgKFRSRUVfT1BFUkFORCAoVFJFRV9PUEVSQU5EICh0LCAwKSwgMCkpOwoJICB0cmVlIGlubmVyMiA9IFRSRUVfVFlQRSAoVFJFRV9PUEVSQU5EIChUUkVFX09QRVJBTkQgKHQsIDEpLCAwKSk7CgkgIGlmIChUUkVFX0NPREUgKGlubmVyMSkgPT0gSU5URUdFUl9UWVBFICYmIFRSRUVfVU5TSUdORUQgKGlubmVyMSkKCSAgICAgICYmIFRSRUVfQ09ERSAoaW5uZXIyKSA9PSBJTlRFR0VSX1RZUEUgJiYgVFJFRV9VTlNJR05FRCAoaW5uZXIyKSkKCSAgICByZXR1cm4gVFlQRV9QUkVDSVNJT04gKGlubmVyMSkgKyBUWVBFX1BSRUNJU0lPTiAoaW5uZXIyKQoJCSAgIDwgVFlQRV9QUkVDSVNJT04gKFRSRUVfVFlQRSAodCkpOwoJfQogICAgICByZXR1cm4gMDsKCiAgICBjYXNlIFRSVU5DX0RJVl9FWFBSOgogICAgY2FzZSBDRUlMX0RJVl9FWFBSOgogICAgY2FzZSBGTE9PUl9ESVZfRVhQUjoKICAgIGNhc2UgUk9VTkRfRElWX0VYUFI6CiAgICAgIHJldHVybiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9PUEVSQU5EICh0LCAwKSkKCSAgICAgJiYgdHJlZV9leHByX25vbm5lZ2F0aXZlX3AgKFRSRUVfT1BFUkFORCAodCwgMSkpOwoKICAgIGNhc2UgVFJVTkNfTU9EX0VYUFI6CiAgICBjYXNlIENFSUxfTU9EX0VYUFI6CiAgICBjYXNlIEZMT09SX01PRF9FWFBSOgogICAgY2FzZSBST1VORF9NT0RfRVhQUjoKICAgICAgcmV0dXJuIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDApKTsKCiAgICBjYXNlIFJESVZfRVhQUjoKICAgICAgcmV0dXJuIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDApKQoJICAgICAmJiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9PUEVSQU5EICh0LCAxKSk7CgogICAgY2FzZSBOT1BfRVhQUjoKICAgICAgewoJdHJlZSBpbm5lcl90eXBlID0gVFJFRV9UWVBFIChUUkVFX09QRVJBTkQgKHQsIDApKTsKCXRyZWUgb3V0ZXJfdHlwZSA9IFRSRUVfVFlQRSAodCk7CgoJaWYgKFRSRUVfQ09ERSAob3V0ZXJfdHlwZSkgPT0gUkVBTF9UWVBFKQoJICB7CgkgICAgaWYgKFRSRUVfQ09ERSAoaW5uZXJfdHlwZSkgPT0gUkVBTF9UWVBFKQoJICAgICAgcmV0dXJuIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDApKTsKCSAgICBpZiAoVFJFRV9DT0RFIChpbm5lcl90eXBlKSA9PSBJTlRFR0VSX1RZUEUpCgkgICAgICB7CgkJaWYgKFRSRUVfVU5TSUdORUQgKGlubmVyX3R5cGUpKQoJCSAgcmV0dXJuIDE7CgkJcmV0dXJuIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDApKTsKCSAgICAgIH0KCSAgfQoJZWxzZSBpZiAoVFJFRV9DT0RFIChvdXRlcl90eXBlKSA9PSBJTlRFR0VSX1RZUEUpCgkgIHsKCSAgICBpZiAoVFJFRV9DT0RFIChpbm5lcl90eXBlKSA9PSBSRUFMX1RZUEUpCgkgICAgICByZXR1cm4gdHJlZV9leHByX25vbm5lZ2F0aXZlX3AgKFRSRUVfT1BFUkFORCAodCwwKSk7CgkgICAgaWYgKFRSRUVfQ09ERSAoaW5uZXJfdHlwZSkgPT0gSU5URUdFUl9UWVBFKQoJICAgICAgcmV0dXJuIFRZUEVfUFJFQ0lTSU9OIChpbm5lcl90eXBlKSA8IFRZUEVfUFJFQ0lTSU9OIChvdXRlcl90eXBlKQoJCSAgICAgICYmIFRSRUVfVU5TSUdORUQgKGlubmVyX3R5cGUpOwoJICB9CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgY2FzZSBDT05EX0VYUFI6CiAgICAgIHJldHVybiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9PUEVSQU5EICh0LCAxKSkKCSYmIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDIpKTsKICAgIGNhc2UgQ09NUE9VTkRfRVhQUjoKICAgICAgcmV0dXJuIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDEpKTsKICAgIGNhc2UgTUlOX0VYUFI6CiAgICAgIHJldHVybiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9PUEVSQU5EICh0LCAwKSkKCSYmIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDEpKTsKICAgIGNhc2UgTUFYX0VYUFI6CiAgICAgIHJldHVybiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9PUEVSQU5EICh0LCAwKSkKCXx8IHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDEpKTsKICAgIGNhc2UgTU9ESUZZX0VYUFI6CiAgICAgIHJldHVybiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9PUEVSQU5EICh0LCAxKSk7CiAgICBjYXNlIEJJTkRfRVhQUjoKICAgICAgcmV0dXJuIHRyZWVfZXhwcl9ub25uZWdhdGl2ZV9wIChUUkVFX09QRVJBTkQgKHQsIDEpKTsKICAgIGNhc2UgU0FWRV9FWFBSOgogICAgICByZXR1cm4gdHJlZV9leHByX25vbm5lZ2F0aXZlX3AgKFRSRUVfT1BFUkFORCAodCwgMCkpOwogICAgY2FzZSBOT05fTFZBTFVFX0VYUFI6CiAgICAgIHJldHVybiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9PUEVSQU5EICh0LCAwKSk7CiAgICBjYXNlIEZMT0FUX0VYUFI6CiAgICAgIHJldHVybiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9PUEVSQU5EICh0LCAwKSk7CiAgICBjYXNlIFJUTF9FWFBSOgogICAgICByZXR1cm4gcnRsX2V4cHJfbm9ubmVnYXRpdmVfcCAoUlRMX0VYUFJfUlRMICh0KSk7CgogICAgY2FzZSBDQUxMX0VYUFI6CiAgICAgIHsKCXRyZWUgZm5kZWNsID0gZ2V0X2NhbGxlZV9mbmRlY2wgKHQpOwoJdHJlZSBhcmdsaXN0ID0gVFJFRV9PUEVSQU5EICh0LCAxKTsKCWlmIChmbmRlY2wKCSAgICAmJiBERUNMX0JVSUxUX0lOIChmbmRlY2wpCgkgICAgJiYgREVDTF9CVUlMVF9JTl9DTEFTUyAoZm5kZWNsKSAhPSBCVUlMVF9JTl9NRCkKCSAgc3dpdGNoIChERUNMX0ZVTkNUSU9OX0NPREUgKGZuZGVjbCkpCgkgICAgewoJICAgIGNhc2UgQlVJTFRfSU5fQ0FCUzoKCSAgICBjYXNlIEJVSUxUX0lOX0NBQlNMOgoJICAgIGNhc2UgQlVJTFRfSU5fQ0FCU0Y6CgkgICAgY2FzZSBCVUlMVF9JTl9FWFA6CgkgICAgY2FzZSBCVUlMVF9JTl9FWFBGOgoJICAgIGNhc2UgQlVJTFRfSU5fRVhQTDoKCSAgICBjYXNlIEJVSUxUX0lOX0VYUDI6CgkgICAgY2FzZSBCVUlMVF9JTl9FWFAyRjoKCSAgICBjYXNlIEJVSUxUX0lOX0VYUDJMOgoJICAgIGNhc2UgQlVJTFRfSU5fRVhQMTA6CgkgICAgY2FzZSBCVUlMVF9JTl9FWFAxMEY6CgkgICAgY2FzZSBCVUlMVF9JTl9FWFAxMEw6CgkgICAgY2FzZSBCVUlMVF9JTl9GQUJTOgoJICAgIGNhc2UgQlVJTFRfSU5fRkFCU0Y6CgkgICAgY2FzZSBCVUlMVF9JTl9GQUJTTDoKCSAgICBjYXNlIEJVSUxUX0lOX0ZGUzoKCSAgICBjYXNlIEJVSUxUX0lOX0ZGU0w6CgkgICAgY2FzZSBCVUlMVF9JTl9GRlNMTDoKCSAgICBjYXNlIEJVSUxUX0lOX1BBUklUWToKCSAgICBjYXNlIEJVSUxUX0lOX1BBUklUWUw6CgkgICAgY2FzZSBCVUlMVF9JTl9QQVJJVFlMTDoKCSAgICBjYXNlIEJVSUxUX0lOX1BPUENPVU5UOgoJICAgIGNhc2UgQlVJTFRfSU5fUE9QQ09VTlRMOgoJICAgIGNhc2UgQlVJTFRfSU5fUE9QQ09VTlRMTDoKCSAgICBjYXNlIEJVSUxUX0lOX1BPVzEwOgoJICAgIGNhc2UgQlVJTFRfSU5fUE9XMTBGOgoJICAgIGNhc2UgQlVJTFRfSU5fUE9XMTBMOgoJICAgIGNhc2UgQlVJTFRfSU5fU1FSVDoKCSAgICBjYXNlIEJVSUxUX0lOX1NRUlRGOgoJICAgIGNhc2UgQlVJTFRfSU5fU1FSVEw6CgkgICAgICByZXR1cm4gMTsKCgkgICAgY2FzZSBCVUlMVF9JTl9BVEFOOgoJICAgIGNhc2UgQlVJTFRfSU5fQVRBTkY6CgkgICAgY2FzZSBCVUlMVF9JTl9BVEFOTDoKCSAgICBjYXNlIEJVSUxUX0lOX0NFSUw6CgkgICAgY2FzZSBCVUlMVF9JTl9DRUlMRjoKCSAgICBjYXNlIEJVSUxUX0lOX0NFSUxMOgoJICAgIGNhc2UgQlVJTFRfSU5fRkxPT1I6CgkgICAgY2FzZSBCVUlMVF9JTl9GTE9PUkY6CgkgICAgY2FzZSBCVUlMVF9JTl9GTE9PUkw6CgkgICAgY2FzZSBCVUlMVF9JTl9ORUFSQllJTlQ6CgkgICAgY2FzZSBCVUlMVF9JTl9ORUFSQllJTlRGOgoJICAgIGNhc2UgQlVJTFRfSU5fTkVBUkJZSU5UTDoKCSAgICBjYXNlIEJVSUxUX0lOX1JPVU5EOgoJICAgIGNhc2UgQlVJTFRfSU5fUk9VTkRGOgoJICAgIGNhc2UgQlVJTFRfSU5fUk9VTkRMOgoJICAgIGNhc2UgQlVJTFRfSU5fVFJVTkM6CgkgICAgY2FzZSBCVUlMVF9JTl9UUlVOQ0Y6CgkgICAgY2FzZSBCVUlMVF9JTl9UUlVOQ0w6CgkgICAgICByZXR1cm4gdHJlZV9leHByX25vbm5lZ2F0aXZlX3AgKFRSRUVfVkFMVUUgKGFyZ2xpc3QpKTsKCgkgICAgY2FzZSBCVUlMVF9JTl9QT1c6CgkgICAgY2FzZSBCVUlMVF9JTl9QT1dGOgoJICAgIGNhc2UgQlVJTFRfSU5fUE9XTDoKCSAgICAgIHJldHVybiB0cmVlX2V4cHJfbm9ubmVnYXRpdmVfcCAoVFJFRV9WQUxVRSAoYXJnbGlzdCkpOwoKCSAgICBkZWZhdWx0OgoJICAgICAgYnJlYWs7CgkgICAgfQogICAgICB9CgogICAgICAvKiAuLi4gZmFsbCB0aHJvdWdoIC4uLiAgKi8KCiAgICBkZWZhdWx0OgogICAgICBpZiAodHJ1dGhfdmFsdWVfcCAoVFJFRV9DT0RFICh0KSkpCgkvKiBUcnV0aCB2YWx1ZXMgZXZhbHVhdGUgdG8gMCBvciAxLCB3aGljaCBpcyBub25uZWdhdGl2ZS4gICovCglyZXR1cm4gMTsKICAgIH0KCiAgLyogV2UgZG9uJ3Qga25vdyBzaWduIG9mIGB0Jywgc28gYmUgY29uc2VydmF0aXZlIGFuZCByZXR1cm4gZmFsc2UuICAqLwogIHJldHVybiAwOwp9CgovKiBSZXR1cm4gdHJ1ZSBpZiBgcicgaXMga25vd24gdG8gYmUgbm9uLW5lZ2F0aXZlLgogICBPbmx5IGhhbmRsZXMgY29uc3RhbnRzIGF0IHRoZSBtb21lbnQuICAqLwoKaW50CnJ0bF9leHByX25vbm5lZ2F0aXZlX3AgKHJ0eCByKQp7CiAgc3dpdGNoIChHRVRfQ09ERSAocikpCiAgICB7CiAgICBjYXNlIENPTlNUX0lOVDoKICAgICAgcmV0dXJuIElOVFZBTCAocikgPj0gMDsKCiAgICBjYXNlIENPTlNUX0RPVUJMRToKICAgICAgaWYgKEdFVF9NT0RFIChyKSA9PSBWT0lEbW9kZSkKCXJldHVybiBDT05TVF9ET1VCTEVfSElHSCAocikgPj0gMDsKICAgICAgcmV0dXJuIDA7CgogICAgY2FzZSBDT05TVF9WRUNUT1I6CiAgICAgIHsKCWludCB1bml0cywgaTsKCXJ0eCBlbHQ7CgoJdW5pdHMgPSBDT05TVF9WRUNUT1JfTlVOSVRTIChyKTsKCglmb3IgKGkgPSAwOyBpIDwgdW5pdHM7ICsraSkKCSAgewoJICAgIGVsdCA9IENPTlNUX1ZFQ1RPUl9FTFQgKHIsIGkpOwoJICAgIGlmICghcnRsX2V4cHJfbm9ubmVnYXRpdmVfcCAoZWx0KSkKCSAgICAgIHJldHVybiAwOwoJICB9CgoJcmV0dXJuIDE7CiAgICAgIH0KCiAgICBjYXNlIFNZTUJPTF9SRUY6CiAgICBjYXNlIExBQkVMX1JFRjoKICAgICAgLyogVGhlc2UgYXJlIGFsd2F5cyBub25uZWdhdGl2ZS4gICovCiAgICAgIHJldHVybiAxOwoKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiAwOwogICAgfQp9CgojaW5jbHVkZSAiZ3QtZm9sZC1jb25zdC5oIgo=