LyogJFhGcmVlODYkICovIC8qIC0qLSBtb2RlOiBjOyBjLWJhc2ljLW9mZnNldDogMyAtKi0gKi8KLyoKICogQ29weXJpZ2h0IDIwMDAgR2FyZXRoIEh1Z2hlcwogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAogKiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCiAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAogKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUgbmV4dAogKiBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlCiAqIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMCiAqIEdBUkVUSCBIVUdIRVMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSCiAqIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOCiAqIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCiAqLwoKLyoKICogQXV0aG9yczoKICoJR2FyZXRoIEh1Z2hlcyA8Z2FyZXRoQHZhbGludXguY29tPgogKglMZWlmIERlbGdhc3MgPGxkZWxnYXNzQHJldGluYWxidXJuLm5ldD4KICoJSm9z6SBGb25zZWNhIDxqX3JfZm9uc2VjYUB5YWhvby5jby51az4KICovCgojaW5jbHVkZSAibWFjaDY0X2NvbnRleHQuaCIKI2luY2x1ZGUgIm1hY2g2NF9zdGF0ZS5oIgojaW5jbHVkZSAibWFjaDY0X2xvY2suaCIKI2luY2x1ZGUgIm1hY2g2NF90ZXguaCIKI2luY2x1ZGUgImRyaXJlbmRlcmJ1ZmZlci5oIgoKI2lmIERFQlVHX0xPQ0tJTkcKY2hhciAqcHJldkxvY2tGaWxlID0gTlVMTDsKaW50ICAgcHJldkxvY2tMaW5lID0gMDsKI2VuZGlmCgoKLyogVXBkYXRlIHRoZSBoYXJkd2FyZSBzdGF0ZS4gIFRoaXMgaXMgY2FsbGVkIGlmIGFub3RoZXIgY29udGV4dCBoYXMKICogZ3JhYmJlZCB0aGUgaGFyZHdhcmUgbG9jaywgd2hpY2ggaW5jbHVkZXMgdGhlIFggc2VydmVyLiAgVGhpcwogKiBmdW5jdGlvbiBhbHNvIHVwZGF0ZXMgdGhlIGRyaXZlcidzIHdpbmRvdyBzdGF0ZSBhZnRlciB0aGUgWCBzZXJ2ZXIKICogbW92ZXMsIHJlc2l6ZXMgb3IgcmVzdGFja3MgYSB3aW5kb3cgLS0gdGhlIGNoYW5nZSB3aWxsIGJlIHJlZmxlY3RlZAogKiBpbiB0aGUgZHJhd2FibGUgcG9zaXRpb24gYW5kIGNsaXAgcmVjdHMuICBTaW5jZSB0aGUgWCBzZXJ2ZXIgZ3JhYnMKICogdGhlIGhhcmR3YXJlIGxvY2sgd2hlbiBpdCBjaGFuZ2VzIHRoZSB3aW5kb3cgc3RhdGUsIHRoaXMgcm91dGluZSB3aWxsCiAqIGF1dG9tYXRpY2FsbHkgYmUgY2FsbGVkIGFmdGVyIHN1Y2ggYSBjaGFuZ2UuCiAqLwp2b2lkIG1hY2g2NEdldExvY2soIG1hY2g2NENvbnRleHRQdHIgbW1lc2EsIEdMdWludCBmbGFncyApCnsKICAgX19EUklkcmF3YWJsZVByaXZhdGUgKmRQcml2ID0gbW1lc2EtPmRyaURyYXdhYmxlOwogICBfX0RSSXNjcmVlblByaXZhdGUgKnNQcml2ID0gbW1lc2EtPmRyaVNjcmVlbjsKICAgZHJtX21hY2g2NF9zYXJlYV90ICpzYXJlYSA9IG1tZXNhLT5zYXJlYTsKICAgaW50IGk7CgogICBkcm1HZXRMb2NrKCBtbWVzYS0+ZHJpRmQsIG1tZXNhLT5oSFdDb250ZXh0LCBmbGFncyApOwoKICAgLyogVGhlIHdpbmRvdyBtaWdodCBoYXZlIG1vdmVkLCBzbyB3ZSBtaWdodCBuZWVkIHRvIGdldCBuZXcgY2xpcAogICAgKiByZWN0cy4KICAgICoKICAgICogTk9URTogVGhpcyByZWxlYXNlcyBhbmQgcmVncmFicyB0aGUgaHcgbG9jayB0byBhbGxvdyB0aGUgWCBzZXJ2ZXIKICAgICogdG8gcmVzcG9uZCB0byB0aGUgRFJJIHByb3RvY29sIHJlcXVlc3QgZm9yIG5ldyBkcmF3YWJsZSBpbmZvLgogICAgKiBTaW5jZSB0aGUgaGFyZHdhcmUgc3RhdGUgZGVwZW5kcyBvbiBoYXZpbmcgdGhlIGxhdGVzdCBkcmF3YWJsZQogICAgKiBjbGlwIHJlY3RzLCBhbGwgc3RhdGUgY2hlY2tpbmcgbXVzdCBiZSBkb25lIF9hZnRlcl8gdGhpcyBjYWxsLgogICAgKi8KICAgRFJJX1ZBTElEQVRFX0RSQVdBQkxFX0lORk8oIHNQcml2LCBkUHJpdiApOyAKCiAgIGlmICggbW1lc2EtPmxhc3RTdGFtcCAhPSBkUHJpdi0+bGFzdFN0YW1wICkgewogICAgICBtbWVzYS0+bGFzdFN0YW1wID0gZFByaXYtPmxhc3RTdGFtcDsKICAgICAgaWYgKG1tZXNhLT5nbEN0eC0+RHJhd0J1ZmZlci0+X0NvbG9yRHJhd0J1ZmZlckluZGV4ZXNbMF0gPT0gQlVGRkVSX0JBQ0tfTEVGVCkKICAgICAgICAgbWFjaDY0U2V0Q2xpcHJlY3RzKCBtbWVzYS0+Z2xDdHgsIEdMX0JBQ0tfTEVGVCApOwogICAgICBlbHNlCiAgICAgICAgIG1hY2g2NFNldENsaXByZWN0cyggbW1lc2EtPmdsQ3R4LCBHTF9GUk9OVF9MRUZUICk7CiAgICAgIGRyaVVwZGF0ZUZyYW1lYnVmZmVyU2l6ZSggbW1lc2EtPmdsQ3R4LCBkUHJpdiApOwogICAgICBtYWNoNjRDYWxjVmlld3BvcnQoIG1tZXNhLT5nbEN0eCApOwogICB9CgogICBtbWVzYS0+ZGlydHkgfD0gKE1BQ0g2NF9VUExPQURfQ09OVEVYVAoJCSAgICB8IE1BQ0g2NF9VUExPQURfTUlTQwoJCSAgICB8IE1BQ0g2NF9VUExPQURfQ0xJUFJFQ1RTKTsKCiAgIC8qIEVYQSByZW5kZXIgYWNjZWxlcmF0aW9uIHVzZXMgdGhlIHRleHR1cmUgZW5naW5lLCBzbyByZXN0b3JlIGl0ICovCiAgIG1tZXNhLT5kaXJ0eSB8PSAoTUFDSDY0X1VQTE9BRF9URVhUVVJFKTsKCiAgIGlmICggc2FyZWEtPmN0eF9vd25lciAhPSBtbWVzYS0+aEhXQ29udGV4dCApIHsKICAgICAgc2FyZWEtPmN0eF9vd25lciA9IG1tZXNhLT5oSFdDb250ZXh0OwogICAgICBtbWVzYS0+ZGlydHkgPSBNQUNINjRfVVBMT0FEX0FMTDsKICAgfQoKICAgZm9yICggaSA9IG1tZXNhLT5maXJzdFRleEhlYXAgOyBpIDwgbW1lc2EtPmxhc3RUZXhIZWFwIDsgaSsrICkgewogICAgICBEUklfQUdFX1RFWFRVUkVTKCBtbWVzYS0+dGV4dHVyZV9oZWFwc1tpXSApOwogICB9Cn0K