Lyogdmk6c2V0IHRzPTggc3RzPTQgc3c9NDoKICoKICogVklNIC0gVmkgSU1wcm92ZWQJCWJ5IEJyYW0gTW9vbGVuYWFyCiAqCQkJCUdVSS9Nb3RpZiBzdXBwb3J0IGJ5IFJvYmVydCBXZWJiCiAqCiAqIERvICI6aGVscCB1Z2FuZGEiICBpbiBWaW0gdG8gcmVhZCBjb3B5aW5nIGFuZCB1c2FnZSBjb25kaXRpb25zLgogKiBEbyAiOmhlbHAgY3JlZGl0cyIgaW4gVmltIHRvIHNlZSBhIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZC4KICogU2VlIFJFQURNRS50eHQgZm9yIGFuIG92ZXJ2aWV3IG9mIHRoZSBWaW0gc291cmNlIGNvZGUuCiAqLwoKI2luY2x1ZGUgPFhtL0Zvcm0uaD4KI2luY2x1ZGUgPFhtL1Jvd0NvbHVtbi5oPgojaW5jbHVkZSA8WG0vUHVzaEIuaD4KI2luY2x1ZGUgPFhtL1RleHQuaD4KI2luY2x1ZGUgPFhtL1RleHRGLmg+CiNpbmNsdWRlIDxYbS9TZXBhcmF0b3IuaD4KI2luY2x1ZGUgPFhtL0xhYmVsLmg+CiNpbmNsdWRlIDxYbS9DYXNjYWRlQi5oPgojaW5jbHVkZSA8WG0vU2Nyb2xsQmFyLmg+CiNpbmNsdWRlIDxYbS9NZW51U2hlbGwuaD4KI2luY2x1ZGUgPFhtL0RyYXdpbmdBLmg+CiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCiMgaW5jbHVkZSA8WG0vUmVwVHlwZS5oPgojZW5kaWYKI2luY2x1ZGUgPFhtL0ZyYW1lLmg+CiNpbmNsdWRlIDxYbS9MYWJlbEcuaD4KI2luY2x1ZGUgPFhtL1RvZ2dsZUJHLmg+CiNpbmNsdWRlIDxYbS9TZXBhcmF0b0cuaD4KCiNpbmNsdWRlIDxYMTEva2V5c3ltLmg+CiNpbmNsdWRlIDxYMTEvWGF0b20uaD4KI2luY2x1ZGUgPFgxMS9TdHJpbmdEZWZzLmg+CiNpbmNsdWRlIDxYMTEvSW50cmluc2ljLmg+CgojaW5jbHVkZSAidmltLmgiCgojaWZkZWYgSEFWRV9YMTFfWFBNX0gKIyBpbmNsdWRlIDxYMTEveHBtLmg+CiNlbHNlCiMgaWZkZWYgSEFWRV9YTV9YUE1QX0gKIyAgaW5jbHVkZSA8WG0vWHBtUC5oPgojIGVuZGlmCiNlbmRpZgoKI2luY2x1ZGUgImd1aV94bWVidy5oIgkvKiBmb3Igb3VyIEVuaGFuY2VkIEJ1dHRvbiBXaWRnZXQgKi8KCiNpZiBkZWZpbmVkKEZFQVRfR1VJX0RJQUxPRykgJiYgZGVmaW5lZChIQVZFX1hQTSkKIyBpbmNsdWRlICIuLi9waXhtYXBzL2FsZXJ0LnhwbSIKIyBpbmNsdWRlICIuLi9waXhtYXBzL2Vycm9yLnhwbSIKIyBpbmNsdWRlICIuLi9waXhtYXBzL2dlbmVyaWMueHBtIgojIGluY2x1ZGUgIi4uL3BpeG1hcHMvaW5mby54cG0iCiMgaW5jbHVkZSAiLi4vcGl4bWFwcy9xdWVzdC54cG0iCiNlbmRpZgoKI2RlZmluZSBNT1RJRl9QT1BVUAoKZXh0ZXJuIFdpZGdldCB2aW1TaGVsbDsKCnN0YXRpYyBXaWRnZXQgdmltRm9ybTsKc3RhdGljIFdpZGdldCB0ZXh0QXJlYUZvcm07CldpZGdldCB0ZXh0QXJlYTsKI2lmZGVmIEZFQVRfVE9PTEJBUgpzdGF0aWMgV2lkZ2V0IHRvb2xCYXJGcmFtZTsKc3RhdGljIFdpZGdldCB0b29sQmFyOwojZW5kaWYKI2lmZGVmIEZFQVRfRk9PVEVSCnN0YXRpYyBXaWRnZXQgZm9vdGVyOwojZW5kaWYKI2lmZGVmIEZFQVRfTUVOVQojIGlmIChYbVZlcnNpb24gPj0gMTAwMikKLyogcmVtZW1iZXIgdGhlIGxhc3Qgc2V0IHZhbHVlIGZvciB0aGUgdGVhcm9mZiBpdGVtICovCnN0YXRpYyBpbnQgdGVhcm9mZl92YWwgPSAoaW50KVhtVEVBUl9PRkZfRU5BQkxFRDsKIyBlbmRpZgpzdGF0aWMgV2lkZ2V0IG1lbnVCYXI7CiNlbmRpZgoKc3RhdGljIHZvaWQgc2Nyb2xsX2NiIF9fQVJHUygoV2lkZ2V0IHcsIFh0UG9pbnRlciBjbGllbnRfZGF0YSwgWHRQb2ludGVyIGNhbGxfZGF0YSkpOwojaWZkZWYgRkVBVF9UT09MQkFSCiMgaWZkZWYgRkVBVF9GT09URVIKc3RhdGljIHZvaWQgdG9vbGJhcmJ1dHRvbl9lbnRlcl9jYiBfX0FSR1MoKFdpZGdldCwgWHRQb2ludGVyLCBYRXZlbnQgKiwgQm9vbGVhbiAqKSk7CnN0YXRpYyB2b2lkIHRvb2xiYXJidXR0b25fbGVhdmVfY2IgX19BUkdTKChXaWRnZXQsIFh0UG9pbnRlciwgWEV2ZW50ICosIEJvb2xlYW4gKikpOwojIGVuZGlmCnN0YXRpYyB2b2lkIHJlc2V0X2ZvY3VzIF9fQVJHUygodm9pZCkpOwojZW5kaWYKI2lmZGVmIEZFQVRfRk9PVEVSCnN0YXRpYyBpbnQgZ3VpX21jaF9jb21wdXRlX2Zvb3Rlcl9oZWlnaHQgX19BUkdTKCh2b2lkKSk7CiNlbmRpZgojaWZkZWYgV1NERUJVRwpzdGF0aWMgdm9pZCBhdHRhY2hEdW1wKFdpZGdldCwgY2hhciAqKTsKI2VuZGlmCgpzdGF0aWMgdm9pZCBndWlfbW90aWZfbWVudV9jb2xvcnMgX19BUkdTKChXaWRnZXQgaWQpKTsKc3RhdGljIHZvaWQgZ3VpX21vdGlmX3Njcm9sbF9jb2xvcnMgX19BUkdTKChXaWRnZXQgaWQpKTsKCiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCiMgZGVmaW5lIFNUUklOR19UQUcgIFhtRk9OVExJU1RfREVGQVVMVF9UQUcKI2Vsc2UKIyBkZWZpbmUgU1RSSU5HX1RBRyAgWG1TVFJJTkdfREVGQVVMVF9DSEFSU0VUCiNlbmRpZgoKLyoKICogQ2FsbC1iYWNrIHJvdXRpbmVzLgogKi8KCi8qIEFSR1NVU0VEICovCiAgICBzdGF0aWMgdm9pZApzY3JvbGxfY2IodywgY2xpZW50X2RhdGEsIGNhbGxfZGF0YSkKICAgIFdpZGdldAl3OwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhLCBjYWxsX2RhdGE7CnsKICAgIHNjcm9sbGJhcl9UICpzYjsKICAgIGxvbmcJdmFsdWU7CiAgICBpbnQJCWRyYWdnaW5nOwoKICAgIHNiID0gZ3VpX2ZpbmRfc2Nyb2xsYmFyKChsb25nKWNsaWVudF9kYXRhKTsKCiAgICB2YWx1ZSA9ICgoWG1TY3JvbGxCYXJDYWxsYmFja1N0cnVjdCAqKWNhbGxfZGF0YSktPnZhbHVlOwogICAgZHJhZ2dpbmcgPSAoKChYbVNjcm9sbEJhckNhbGxiYWNrU3RydWN0ICopY2FsbF9kYXRhKS0+cmVhc29uID09CgkJCQkJCQkgICAgICAoaW50KVhtQ1JfRFJBRyk7CiAgICBndWlfZHJhZ19zY3JvbGxiYXIoc2IsIHZhbHVlLCBkcmFnZ2luZyk7Cn0KCi8qCiAqIEVuZCBvZiBjYWxsLWJhY2sgcm91dGluZXMKICovCgovKgogKiBJbXBsZW1lbnQgdGhyZWUgZGltZW5zaW9uYWwgc2hhZGluZyBvZiBpbnNlbnNpdGl2ZSBsYWJlbHMuCiAqIEJ5IE1hcmNpbiBEYWxlY2tpLgogKi8KCiNpbmNsdWRlIDxYbS9YbVAuaD4KI2luY2x1ZGUgPFhtL0xhYmVsUC5oPgoKc3RhdGljIFh0RXhwb3NlUHJvYyBvbGRfbGFiZWxfZXhwb3NlID0gTlVMTDsKCnN0YXRpYyB2b2lkIGxhYmVsX2V4cG9zZSBfX0FSR1MoKFdpZGdldCBfdywgWEV2ZW50ICpfZXZlbnQsIFJlZ2lvbiBfcmVnaW9uKSk7CgogICAgc3RhdGljIHZvaWQKbGFiZWxfZXhwb3NlKF93LCBfZXZlbnQsIF9yZWdpb24pCiAgICBXaWRnZXQJX3c7CiAgICBYRXZlbnQJKl9ldmVudDsKICAgIFJlZ2lvbglfcmVnaW9uOwp7CiAgICBHQwkJICAgIGluc2Vuc2l0aXZlR0M7CiAgICBYbUxhYmVsV2lkZ2V0ICAgbHcgPSAoWG1MYWJlbFdpZGdldClfdzsKICAgIHVuc2lnbmVkIGNoYXIgICBsYWJlbF90eXBlID0gKGludClYbVNUUklORzsKCiAgICBYdFZhR2V0VmFsdWVzKF93LCBYbU5sYWJlbFR5cGUsICZsYWJlbF90eXBlLCAoWHRQb2ludGVyKTApOwoKICAgIGlmIChYdElzU2Vuc2l0aXZlKF93KSB8fCBsYWJlbF90eXBlICE9IChpbnQpWG1TVFJJTkcpCgkoKm9sZF9sYWJlbF9leHBvc2UpKF93LCBfZXZlbnQsIF9yZWdpb24pOwogICAgZWxzZQogICAgewoJWEdDVmFsdWVzICAgdmFsdWVzOwoJWHRHQ01hc2sgICAgbWFzazsKCVh0R0NNYXNrICAgIGR5bmFtaWM7CglYRm9udFN0cnVjdCAqZnM7CgoJX1htRm9udExpc3RHZXREZWZhdWx0Rm9udChsdy0+bGFiZWwuZm9udCwgJmZzKTsKCgkvKiBGSVhNRTogd2Ugc2hvdWxkIGJlIGRvaW5nIHRoZSB3aG9sZSBkcmF3aW5nIG91cnNlbGYgaGVyZS4gKi8KCWluc2Vuc2l0aXZlR0MgPSBsdy0+bGFiZWwuaW5zZW5zaXRpdmVfR0M7CgoJbWFzayA9IEdDRm9yZWdyb3VuZCB8IEdDQmFja2dyb3VuZCB8IEdDR3JhcGhpY3NFeHBvc3VyZXM7CglkeW5hbWljID0gR0NDbGlwTWFzayB8IEdDQ2xpcFhPcmlnaW4gfCBHQ0NsaXBZT3JpZ2luOwoJdmFsdWVzLmdyYXBoaWNzX2V4cG9zdXJlcyA9IEZhbHNlOwoKCWlmIChmcyAhPSAwKQoJewoJICAgIG1hc2sgfD0gR0NGb250OwoJICAgIHZhbHVlcy5mb250ID0gZnMtPmZpZDsKCX0KCglpZiAobHctPnByaW1pdGl2ZS50b3Bfc2hhZG93X3BpeG1hcCAhPSBOb25lCgkJJiYgbHctPnByaW1pdGl2ZS50b3Bfc2hhZG93X3BpeG1hcCAhPSBYbVVOU1BFQ0lGSUVEX1BJWE1BUCkKCXsKCSAgICBtYXNrIHw9IEdDRmlsbFN0eWxlIHwgR0NUaWxlOwoJICAgIHZhbHVlcy5maWxsX3N0eWxlID0gRmlsbFRpbGVkOwoJICAgIHZhbHVlcy50aWxlID0gbHctPnByaW1pdGl2ZS50b3Bfc2hhZG93X3BpeG1hcDsKCX0KCglsdy0+bGFiZWwuVGV4dFJlY3QueCArPSAxOwoJbHctPmxhYmVsLlRleHRSZWN0LnkgKz0gMTsKCWlmIChsdy0+bGFiZWwuX2FjY190ZXh0ICE9IDApCgl7CgkgICAgbHctPmxhYmVsLmFjY19UZXh0UmVjdC54ICs9IDE7CgkgICAgbHctPmxhYmVsLmFjY19UZXh0UmVjdC55ICs9IDE7Cgl9CgoJdmFsdWVzLmZvcmVncm91bmQgPSBsdy0+cHJpbWl0aXZlLnRvcF9zaGFkb3dfY29sb3I7Cgl2YWx1ZXMuYmFja2dyb3VuZCA9IGx3LT5jb3JlLmJhY2tncm91bmRfcGl4ZWw7CgoJbHctPmxhYmVsLmluc2Vuc2l0aXZlX0dDID0gWHRBbGxvY2F0ZUdDKChXaWRnZXQpbHcsIDAsIG1hc2ssCgkJCQkJICAgICAgICZ2YWx1ZXMsIGR5bmFtaWMsIChYdEdDTWFzaykwKTsKCSgqb2xkX2xhYmVsX2V4cG9zZSkoX3csIF9ldmVudCwgX3JlZ2lvbik7CglYdFJlbGVhc2VHQyhfdywgbHctPmxhYmVsLmluc2Vuc2l0aXZlX0dDKTsKCglsdy0+bGFiZWwuVGV4dFJlY3QueCAtPSAxOwoJbHctPmxhYmVsLlRleHRSZWN0LnkgLT0gMTsKCWlmIChsdy0+bGFiZWwuX2FjY190ZXh0ICE9IDApCgl7CgkgICAgbHctPmxhYmVsLmFjY19UZXh0UmVjdC54IC09IDE7CgkgICAgbHctPmxhYmVsLmFjY19UZXh0UmVjdC55IC09IDE7Cgl9CgoJdmFsdWVzLmZvcmVncm91bmQgPSBsdy0+cHJpbWl0aXZlLmJvdHRvbV9zaGFkb3dfY29sb3I7Cgl2YWx1ZXMuYmFja2dyb3VuZCA9IGx3LT5jb3JlLmJhY2tncm91bmRfcGl4ZWw7CgoJbHctPmxhYmVsLmluc2Vuc2l0aXZlX0dDID0gWHRBbGxvY2F0ZUdDKChXaWRnZXQpIGx3LCAwLCBtYXNrLAoJCQkJCSAgICAgICAmdmFsdWVzLCBkeW5hbWljLCAoWHRHQ01hc2spMCk7CgkoKm9sZF9sYWJlbF9leHBvc2UpKF93LCBfZXZlbnQsIF9yZWdpb24pOwoJWHRSZWxlYXNlR0MoX3csIGx3LT5sYWJlbC5pbnNlbnNpdGl2ZV9HQyk7CgoJbHctPmxhYmVsLmluc2Vuc2l0aXZlX0dDID0gaW5zZW5zaXRpdmVHQzsKICAgIH0KfQoKLyoKICogQ3JlYXRlIGFsbCB0aGUgbW90aWYgd2lkZ2V0cyBuZWNlc3NhcnkuCiAqLwogICAgdm9pZApndWlfeDExX2NyZWF0ZV93aWRnZXRzKCkKewogICAgLyoKICAgICAqIEluc3RhbGwgdGhlIDNEIHNoYWRlIGVmZmVjdCBkcmF3aW5nIHJvdXRpbmVzLgogICAgICovCiAgICBpZiAob2xkX2xhYmVsX2V4cG9zZSA9PSBOVUxMKQogICAgewoJb2xkX2xhYmVsX2V4cG9zZSA9IHhtTGFiZWxXaWRnZXRDbGFzcy0+Y29yZV9jbGFzcy5leHBvc2U7Cgl4bUxhYmVsV2lkZ2V0Q2xhc3MtPmNvcmVfY2xhc3MuZXhwb3NlID0gbGFiZWxfZXhwb3NlOwogICAgfQoKICAgIC8qCiAgICAgKiBTdGFydCBvdXQgYnkgYWRkaW5nIHRoZSBjb25maWd1cmVkIGJvcmRlciB3aWR0aCBpbnRvIHRoZSBib3JkZXIgb2Zmc2V0CiAgICAgKi8KICAgIGd1aS5ib3JkZXJfb2Zmc2V0ID0gZ3VpLmJvcmRlcl93aWR0aDsKCiAgICAvKgogICAgICogSW5zdGFsbCB0aGUgdGVhck9mZk1vZGVsIHJlc291cmNlIGNvbnZlcnRlci4KICAgICAqLwojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQogICAgWG1SZXBUeXBlSW5zdGFsbFRlYXJPZmZNb2RlbENvbnZlcnRlcigpOwojZW5kaWYKCiAgICAvKiBNYWtlIHN1cmUgdGhlICJRdWl0IiBtZW51IGVudHJ5IG9mIHRoZSB3aW5kb3cgbWFuYWdlciBpcyBpZ25vcmVkICovCiAgICBYdFZhU2V0VmFsdWVzKHZpbVNoZWxsLCBYbU5kZWxldGVSZXNwb25zZSwgWG1ET19OT1RISU5HLCBOVUxMKTsKCiAgICB2aW1Gb3JtID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInZpbUZvcm0iLAoJeG1Gb3JtV2lkZ2V0Q2xhc3MsIHZpbVNoZWxsLAoJWG1OYm9yZGVyV2lkdGgsIDAsCglYbU5oaWdobGlnaHRUaGlja25lc3MsIDAsCglYbU5zaGFkb3dUaGlja25lc3MsIDAsCglYbU5tYXJnaW5XaWR0aCwgMCwKCVhtTm1hcmdpbkhlaWdodCwgMCwKCVhtTnJlc2l6ZVBvbGljeSwgWG1SRVNJWkVfQU5ZLAoJTlVMTCk7CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnModmltRm9ybSk7CgojaWZkZWYgRkVBVF9NRU5VCiAgICB7CglBcmcgYWxbN107IC8qIE1ha2Ugc3VyZSB0aGVyZSBpcyBlbm91Z2ggcm9vbSBmb3IgYXJndW1lbnRzISAqLwoJaW50IGFjID0gMDsKCiMgaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJWHRTZXRBcmcoYWxbYWNdLCBYbU50ZWFyT2ZmTW9kZWwsIHRlYXJvZmZfdmFsKTsgYWMrKzsKIyBlbmRpZgoJWHRTZXRBcmcoYWxbYWNdLCBYbU5sZWZ0QXR0YWNobWVudCwgIFhtQVRUQUNIX0ZPUk0pOyBhYysrOwoJWHRTZXRBcmcoYWxbYWNdLCBYbU50b3BBdHRhY2htZW50LCAgIFhtQVRUQUNIX0ZPUk0pOyBhYysrOwoJWHRTZXRBcmcoYWxbYWNdLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBhYysrOwojIGlmbmRlZiBGRUFUX1RPT0xCQVIKCS8qIEFsd2F5cyBzdGljayB0byByaWdodCBoYW5kIHNpZGUuICovCglYdFNldEFyZyhhbFthY10sIFhtTnJpZ2h0T2Zmc2V0LCAwKTsgYWMrKzsKIyBlbmRpZgoJWHRTZXRBcmcoYWxbYWNdLCBYbU5tYXJnaW5IZWlnaHQsIDApOyBhYysrOwoJbWVudUJhciA9IFhtQ3JlYXRlTWVudUJhcih2aW1Gb3JtLCAibWVudUJhciIsIGFsLCBhYyk7CglYdE1hbmFnZUNoaWxkKG1lbnVCYXIpOwoKCS8qIFJlbWVtYmVyIHRoZSBkZWZhdWx0IGNvbG9ycywgbmVlZGVkIGZvciAiOmhpIGNsZWFyIi4gKi8KCVh0VmFHZXRWYWx1ZXMobWVudUJhciwKCSAgICBYbU5iYWNrZ3JvdW5kLCAmZ3VpLm1lbnVfZGVmX2JnX3BpeGVsLAoJICAgIFhtTmZvcmVncm91bmQsICZndWkubWVudV9kZWZfZmdfcGl4ZWwsCgkgICAgTlVMTCk7CglndWlfbW90aWZfbWVudV9jb2xvcnMobWVudUJhcik7CiAgICB9CiNlbmRpZgoKI2lmZGVmIEZFQVRfVE9PTEJBUgogICAgLyoKICAgICAqIENyZWF0ZSBhbiBlbXB0eSBUb29sQmFyLiBXZSBzaG91bGQgZ2V0IGJ1dHRvbnMgZGVmaW5lZCBmcm9tIG1lbnUudmltLgogICAgICovCiAgICB0b29sQmFyRnJhbWUgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJ0b29sQmFyRnJhbWUiLAoJeG1GcmFtZVdpZGdldENsYXNzLCB2aW1Gb3JtLAoJWG1Oc2hhZG93VGhpY2tuZXNzLCAwLAoJWG1ObWFyZ2luSGVpZ2h0LCAwLAoJWG1ObWFyZ2luV2lkdGgsIDAsCglYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCU5VTEwpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHRvb2xCYXJGcmFtZSk7CgogICAgdG9vbEJhciA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJ0b29sQmFyIiwKCXhtUm93Q29sdW1uV2lkZ2V0Q2xhc3MsIHRvb2xCYXJGcmFtZSwKCVhtTmNoaWxkVHlwZSwgWG1GUkFNRV9XT1JLQVJFQV9DSElMRCwKCVhtTnJvd0NvbHVtblR5cGUsIFhtV09SS19BUkVBLAoJWG1Ob3JpZW50YXRpb24sIFhtSE9SSVpPTlRBTCwKCVhtTnRyYXZlcnNhbE9uLCBGYWxzZSwKCVhtTmlzSG9tb2dlbmVvdXMsIEZhbHNlLAoJWG1OcGFja2luZywgWG1QQUNLX1RJR0hULAoJWG1Oc3BhY2luZywgMCwKCVhtTnNoYWRvd1RoaWNrbmVzcywgMCwKCVhtTmhpZ2hsaWdodFRoaWNrbmVzcywgMCwKCVhtTm1hcmdpbkhlaWdodCwgMCwKCVhtTm1hcmdpbldpZHRoLCAwLAoJWG1OYWRqdXN0TGFzdCwgVHJ1ZSwKCU5VTEwpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHRvb2xCYXIpOwoKI2VuZGlmCgogICAgdGV4dEFyZWFGb3JtID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInRleHRBcmVhRm9ybSIsCgl4bUZvcm1XaWRnZXRDbGFzcywgdmltRm9ybSwKCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglYbU5tYXJnaW5XaWR0aCwgMCwKCVhtTm1hcmdpbkhlaWdodCwgMCwKCVhtTnJlc2l6ZVBvbGljeSwgWG1SRVNJWkVfQU5ZLAoJTlVMTCk7CiAgICBndWlfbW90aWZfc2Nyb2xsX2NvbG9ycyh0ZXh0QXJlYUZvcm0pOwoKICAgIHRleHRBcmVhID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInRleHRBcmVhIiwKCXhtRHJhd2luZ0FyZWFXaWRnZXRDbGFzcywgdGV4dEFyZWFGb3JtLAoJWG1OZm9yZWdyb3VuZCwgZ3VpLm5vcm1fcGl4ZWwsCglYbU5iYWNrZ3JvdW5kLCBndWkuYmFja19waXhlbCwKCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgoJLyoKCSAqIFRoZXNlIHRha2Ugc29tZSBjb250cm9sIGF3YXkgZnJvbSB0aGUgdXNlciwgYnV0IGF2b2lkcyBtYWtpbmcgdGhlbQoJICogYWRkIHJlc291cmNlcyB0byBnZXQgYSBkZWNlbnQgbG9va2luZyBzZXR1cC4KCSAqLwoJWG1OYm9yZGVyV2lkdGgsIDAsCglYbU5oaWdobGlnaHRUaGlja25lc3MsIDAsCglYbU5zaGFkb3dUaGlja25lc3MsIDAsCglOVUxMKTsKCiNpZmRlZiBGRUFUX0ZPT1RFUgogICAgLyoKICAgICAqIENyZWF0ZSB0aGUgRm9vdGVyLgogICAgICovCiAgICBmb290ZXIgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJmb290ZXIiLAoJeG1MYWJlbEdhZGdldENsYXNzLCB2aW1Gb3JtLAoJWG1OYWxpZ25tZW50LCBYbUFMSUdOTUVOVF9CRUdJTk5JTkcsCglYbU5tYXJnaW5IZWlnaHQsIDAsCglYbU5tYXJnaW5XaWR0aCwgMCwKCVhtTnRyYXZlcnNhbE9uLCBGYWxzZSwKCVhtTnJlY29tcHV0ZVNpemUsIEZhbHNlLAoJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglYbU5sZWZ0T2Zmc2V0LCA1LAoJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCU5VTEwpOwogICAgZ3VpX21jaF9zZXRfZm9vdGVyKChjaGFyX3UgKikgIiIpOwojZW5kaWYKCiAgICAvKgogICAgICogSW5zdGFsbCB0aGUgY2FsbGJhY2tzLgogICAgICovCiAgICBndWlfeDExX2NhbGxiYWNrcyh0ZXh0QXJlYSwgdmltRm9ybSk7CgogICAgLyogUHJldGVuZCB3ZSBkb24ndCBoYXZlIGlucHV0IGZvY3VzLCB3ZSB3aWxsIGdldCBhbiBldmVudCBpZiB3ZSBkby4gKi8KICAgIGd1aS5pbl9mb2N1cyA9IEZBTFNFOwp9CgovKgogKiBDYWxsZWQgd2hlbiB0aGUgR1VJIGlzIG5vdCBnb2luZyB0byBzdGFydCBhZnRlciBhbGwuCiAqLwogICAgdm9pZApndWlfeDExX2Rlc3Ryb3lfd2lkZ2V0cygpCnsKICAgIHRleHRBcmVhID0gTlVMTDsKI2lmZGVmIEZFQVRfTUVOVQogICAgbWVudUJhciA9IE5VTEw7CiNlbmRpZgp9CgovKkFSR1NVU0VEKi8KICAgIHZvaWQKZ3VpX21jaF9zZXRfdGV4dF9hcmVhX3Bvcyh4LCB5LCB3LCBoKQogICAgaW50CSAgICB4OwogICAgaW50CSAgICB5OwogICAgaW50CSAgICB3OwogICAgaW50CSAgICBoOwp7CiNpZmRlZiBGRUFUX1RPT0xCQVIKICAgIC8qIEdpdmUga2V5Ym9hcmQgZm9jdXMgdG8gdGhlIHRleHRBcmVhIGluc3RlYWQgb2YgdGhlIHRvb2xiYXIuICovCiAgICByZXNldF9mb2N1cygpOwojZW5kaWYKfQoKICAgIHZvaWQKZ3VpX3gxMV9zZXRfYmFja19jb2xvcigpCnsKICAgIGlmICh0ZXh0QXJlYSAhPSBOVUxMKQojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJWG1DaGFuZ2VDb2xvcih0ZXh0QXJlYSwgZ3VpLmJhY2tfcGl4ZWwpOwojZWxzZQoJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYSwKCQkgIFhtTmJhY2tncm91bmQsIGd1aS5iYWNrX3BpeGVsLAoJCSAgTlVMTCk7CiNlbmRpZgp9CgovKgogKiBNYW5hZ2UgZGlhbG9nIGNlbnRlcmVkIG9uIHBvaW50ZXIuIFRoaXMgY291bGQgYmUgdXNlZCBieSB0aGUgQXRoZW5hIGNvZGUgYXMKICogd2VsbC4KICovCiAgICB2b2lkCm1hbmFnZV9jZW50ZXJlZChkaWFsb2dfY2hpbGQpCiAgICBXaWRnZXQgZGlhbG9nX2NoaWxkOwp7CiAgICBXaWRnZXQgc2hlbGwgPSBYdFBhcmVudChkaWFsb2dfY2hpbGQpOwogICAgV2luZG93IHJvb3QsIGNoaWxkOwogICAgdW5zaWduZWQgaW50IG1hc2s7CiAgICB1bnNpZ25lZCBpbnQgd2lkdGgsIGhlaWdodCwgYm9yZGVyX3dpZHRoLCBkZXB0aDsKICAgIGludCB4LCB5LCB3aW5feCwgd2luX3ksIG1heFgsIG1heFk7CiAgICBCb29sZWFuIG1hcHBlZFdoZW5NYW5hZ2VkOwoKICAgIC8qIFRlbXBvcmFyaWx5IHNldCB2YWx1ZSBvZiBYbU5tYXBwZWRXaGVuTWFuYWdlZAogICAgICAgdG8gc3RvcCB0aGUgZGlhbG9nIGZyb20gcG9wcGluZyB1cCByaWdodCBhd2F5ICovCiAgICBYdFZhR2V0VmFsdWVzKHNoZWxsLCBYbU5tYXBwZWRXaGVuTWFuYWdlZCwgJm1hcHBlZFdoZW5NYW5hZ2VkLCAwKTsKICAgIFh0VmFTZXRWYWx1ZXMoc2hlbGwsIFhtTm1hcHBlZFdoZW5NYW5hZ2VkLCBGYWxzZSwgMCk7CgogICAgWHRNYW5hZ2VDaGlsZChkaWFsb2dfY2hpbGQpOwoKICAgIC8qIEdldCB0aGUgcG9pbnRlciBwb3NpdGlvbiAoeCwgeSkgKi8KICAgIFhRdWVyeVBvaW50ZXIoWHREaXNwbGF5KHNoZWxsKSwgWHRXaW5kb3coc2hlbGwpLCAmcm9vdCwgJmNoaWxkLAoJCSAgJngsICZ5LCAmd2luX3gsICZ3aW5feSwgJm1hc2spOwoKICAgIC8qIFRyYW5zbGF0ZSB0aGUgcG9pbnRlciBwb3NpdGlvbiAoeCwgeSkgaW50byBhIHBvc2l0aW9uIGZvciB0aGUgbmV3CiAgICAgICB3aW5kb3cgdGhhdCB3aWxsIHBsYWNlIHRoZSBwb2ludGVyIGF0IGl0cyBjZW50ZXIgKi8KICAgIFhHZXRHZW9tZXRyeShYdERpc3BsYXkoc2hlbGwpLCBYdFdpbmRvdyhzaGVsbCksICZyb290LCAmd2luX3gsICZ3aW5feSwKCQkgJndpZHRoLCAmaGVpZ2h0LCAmYm9yZGVyX3dpZHRoLCAmZGVwdGgpOwogICAgd2lkdGggKz0gMiAqIGJvcmRlcl93aWR0aDsKICAgIGhlaWdodCArPSAyICogYm9yZGVyX3dpZHRoOwogICAgeCAtPSB3aWR0aCAvIDI7CiAgICB5IC09IGhlaWdodCAvIDI7CgogICAgLyogRW5zdXJlIHRoYXQgdGhlIGRpYWxvZyByZW1haW5zIG9uIHNjcmVlbiAqLwogICAgbWF4WCA9IFh0U2NyZWVuKHNoZWxsKS0+d2lkdGggLSB3aWR0aDsKICAgIG1heFkgPSBYdFNjcmVlbihzaGVsbCktPmhlaWdodCAtIGhlaWdodDsKICAgIGlmICh4IDwgMCkKCXggPSAwOwogICAgaWYgKHggPiBtYXhYKQoJeCA9IG1heFg7CiAgICBpZiAoeSA8IDApCgl5ID0gMDsKICAgIGlmICh5ID4gbWF4WSkKCXkgPSBtYXhZOwoKICAgIC8qIFNldCBkZXNpcmVkIHdpbmRvdyBwb3NpdGlvbiBpbiB0aGUgRGlhbG9nU2hlbGwgKi8KICAgIFh0VmFTZXRWYWx1ZXMoc2hlbGwsIFhtTngsIHgsIFhtTnksIHksIE5VTEwpOwoKICAgIC8qIE1hcCB0aGUgd2lkZ2V0ICovCiAgICBYdE1hcFdpZGdldChzaGVsbCk7CgogICAgLyogUmVzdG9yZSB0aGUgdmFsdWUgb2YgWG1ObWFwcGVkV2hlbk1hbmFnZWQgKi8KICAgIFh0VmFTZXRWYWx1ZXMoc2hlbGwsIFhtTm1hcHBlZFdoZW5NYW5hZ2VkLCBtYXBwZWRXaGVuTWFuYWdlZCwgMCk7Cn0KCiNpZiBkZWZpbmVkKEZFQVRfTUVOVSkgfHwgZGVmaW5lZChGRUFUX1NVTl9XT1JLU0hPUCkgXAoJfHwgZGVmaW5lZChGRUFUX0dVSV9ESUFMT0cpIHx8IGRlZmluZWQoUFJPVE8pCgovKgogKiBFbmNhcHN1bGF0ZSB0aGUgd2F5IGFuIFhtRm9udExpc3QgaXMgY3JlYXRlZC4KICovCiAgICBYbUZvbnRMaXN0Cmd1aV9tb3RpZl9jcmVhdGVfZm9udGxpc3QoZm9udCkKICAgIFhGb250U3RydWN0ICAgICpmb250Owp7CiAgICBYbUZvbnRMaXN0IGZvbnRfbGlzdDsKCiMgaWYgKFhtVmVyc2lvbiA8PSAxMDAxKQogICAgLyogTW90aWYgMS4xIG1ldGhvZCAqLwogICAgZm9udF9saXN0ID0gWG1Gb250TGlzdENyZWF0ZShmb250LCBTVFJJTkdfVEFHKTsKIyBlbHNlCiAgICAvKiBNb3RpZiAxLjIgbWV0aG9kICovCiAgICBYbUZvbnRMaXN0RW50cnkgZm9udF9saXN0X2VudHJ5OwoKICAgIGZvbnRfbGlzdF9lbnRyeSA9IFhtRm9udExpc3RFbnRyeUNyZWF0ZShTVFJJTkdfVEFHLCBYbUZPTlRfSVNfRk9OVCwKCQkJCQkgICAgKFh0UG9pbnRlcilmb250KTsKICAgIGZvbnRfbGlzdCA9IFhtRm9udExpc3RBcHBlbmRFbnRyeShOVUxMLCBmb250X2xpc3RfZW50cnkpOwogICAgWG1Gb250TGlzdEVudHJ5RnJlZSgmZm9udF9saXN0X2VudHJ5KTsKIyBlbmRpZgogICAgcmV0dXJuIGZvbnRfbGlzdDsKfQoKIyBpZiAoKFhtVmVyc2lvbiA+IDEwMDEpICYmIGRlZmluZWQoRkVBVF9YRk9OVFNFVCkpIHx8IGRlZmluZWQoUFJPVE8pCiAgICBYbUZvbnRMaXN0Cmd1aV9tb3RpZl9mb250c2V0MmZvbnRsaXN0KGZvbnRzZXQpCiAgICBYRm9udFNldAkqZm9udHNldDsKewogICAgWG1Gb250TGlzdCBmb250X2xpc3Q7CgogICAgLyogTW90aWYgMS4yIG1ldGhvZCAqLwogICAgWG1Gb250TGlzdEVudHJ5IGZvbnRfbGlzdF9lbnRyeTsKCiAgICBmb250X2xpc3RfZW50cnkgPSBYbUZvbnRMaXN0RW50cnlDcmVhdGUoU1RSSU5HX1RBRywKCQkJCQkgICAgWG1GT05UX0lTX0ZPTlRTRVQsCgkJCQkJICAgIChYdFBvaW50ZXIpKmZvbnRzZXQpOwogICAgZm9udF9saXN0ID0gWG1Gb250TGlzdEFwcGVuZEVudHJ5KE5VTEwsIGZvbnRfbGlzdF9lbnRyeSk7CiAgICBYbUZvbnRMaXN0RW50cnlGcmVlKCZmb250X2xpc3RfZW50cnkpOwogICAgcmV0dXJuIGZvbnRfbGlzdDsKfQojIGVuZGlmCgojZW5kaWYKCiNpZiBkZWZpbmVkKEZFQVRfTUVOVSkgfHwgZGVmaW5lZChQUk9UTykKLyoKICogTWVudSBzdHVmZi4KICovCgpzdGF0aWMgdm9pZCBndWlfbW90aWZfYWRkX2FjdGV4dCBfX0FSR1MoKHZpbW1lbnVfVCAqbWVudSkpOwojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQpzdGF0aWMgdm9pZCB0b2dnbGVfdGVhcm9mZiBfX0FSR1MoKFdpZGdldCB3aWQpKTsKc3RhdGljIHZvaWQgZ3VpX21jaF9yZWN1cnNlX3RlYXJvZmZzIF9fQVJHUygodmltbWVudV9UICptZW51KSk7CiNlbmRpZgpzdGF0aWMgdm9pZCBzdWJtZW51X2NoYW5nZSBfX0FSR1MoKHZpbW1lbnVfVCAqbXAsIGludCBjb2xvcnMpKTsKCnN0YXRpYyB2b2lkIGRvX3NldF9tbmVtb25pY3MgX19BUkdTKChpbnQgZW5hYmxlKSk7CnN0YXRpYyBpbnQgbWVudV9lbmFibGVkID0gVFJVRTsKCiAgICB2b2lkCmd1aV9tY2hfZW5hYmxlX21lbnUoZmxhZykKICAgIGludAkgICAgZmxhZzsKewogICAgaWYgKGZsYWcpCiAgICB7CglYdE1hbmFnZUNoaWxkKG1lbnVCYXIpOwojaWZkZWYgRkVBVF9UT09MQkFSCglpZiAoWHRJc01hbmFnZWQoWHRQYXJlbnQodG9vbEJhcikpKQoJewoJICAgIC8qIHRvb2xCYXIgaXMgYXR0YWNoZWQgdG8gdG9wIGZvcm0gKi8KCSAgICBYdFZhU2V0VmFsdWVzKFh0UGFyZW50KHRvb2xCYXIpLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU50b3BXaWRnZXQsIG1lbnVCYXIsCgkJTlVMTCk7CgkgICAgWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCVhtTnRvcFdpZGdldCwgWHRQYXJlbnQodG9vbEJhciksCgkJTlVMTCk7Cgl9CgllbHNlCiNlbmRpZgoJewoJICAgIFh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU50b3BXaWRnZXQsIG1lbnVCYXIsCgkJTlVMTCk7Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CglYdFVubWFuYWdlQ2hpbGQobWVudUJhcik7CiNpZmRlZiBGRUFUX1RPT0xCQVIKCWlmIChYdElzTWFuYWdlZChYdFBhcmVudCh0b29sQmFyKSkpCgl7CgkgICAgWHRWYVNldFZhbHVlcyhYdFBhcmVudCh0b29sQmFyKSwKCQlYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCU5VTEwpOwoJICAgIFh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU50b3BXaWRnZXQsIFh0UGFyZW50KHRvb2xCYXIpLAoJCU5VTEwpOwoJfQoJZWxzZQojZW5kaWYKCXsKCSAgICBYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQlYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCU5VTEwpOwoJfQogICAgfQoKfQoKLyoKICogRW5hYmxlIG9yIGRpc2FibGUgbW5lbW9uaWNzIGZvciB0aGUgdG9wbGV2ZWwgbWVudXMuCiAqLwogICAgdm9pZApndWlfbW90aWZfc2V0X21uZW1vbmljcyhlbmFibGUpCiAgICBpbnQJCWVuYWJsZTsKewogICAgLyoKICAgICAqIERvbid0IGVuYWJsZSBtZW51IG1uZW1vbmljcyB3aGVuIHRoZSBtZW51IGJhciBpcyBkaXNhYmxlZCwgTGVzc1RpZgogICAgICogY3Jhc2hlcyB3aGVuIHVzaW5nIGEgbW5lbW9uaWMgdGhlbi4KICAgICAqLwogICAgaWYgKCFtZW51X2VuYWJsZWQpCgllbmFibGUgPSBGQUxTRTsKICAgIGRvX3NldF9tbmVtb25pY3MoZW5hYmxlKTsKfQoKICAgIHN0YXRpYyB2b2lkCmRvX3NldF9tbmVtb25pY3MoZW5hYmxlKQogICAgaW50CQllbmFibGU7CnsKICAgIHZpbW1lbnVfVAkqbWVudTsKCiAgICBmb3IgKG1lbnUgPSByb290X21lbnU7IG1lbnUgIT0gTlVMTDsgbWVudSA9IG1lbnUtPm5leHQpCglpZiAobWVudS0+aWQgIT0gKFdpZGdldCkwKQoJICAgIFh0VmFTZXRWYWx1ZXMobWVudS0+aWQsCgkJICAgIFhtTm1uZW1vbmljLCBlbmFibGUgPyBtZW51LT5tbmVtb25pYyA6IE5VTCwKCQkgICAgTlVMTCk7Cn0KCiAgICB2b2lkCmd1aV9tY2hfYWRkX21lbnUobWVudSwgaWR4KQogICAgdmltbWVudV9UCSptZW51OwogICAgaW50CQlpZHg7CnsKICAgIFhtU3RyaW5nCWxhYmVsOwogICAgV2lkZ2V0CXNoZWxsOwogICAgdmltbWVudV9UCSpwYXJlbnQgPSBtZW51LT5wYXJlbnQ7CgojaWZkZWYgTU9USUZfUE9QVVAKICAgIGlmIChtZW51X2lzX3BvcHVwKG1lbnUtPm5hbWUpKQogICAgewoJQXJnIGFyZ1syXTsKCWludCBuID0gMDsKCgkvKiBPbmx5IGNyZWF0ZSB0aGUgcG9wdXAgbWVudSB3aGVuIGl0J3MgYWN0dWFsbHkgdXNlZCwgb3RoZXJ3aXNlIHRoZXJlCgkgKiBpcyBhIGRlbGF5IHdoZW4gdXNpbmcgdGhlIHJpZ2h0IG1vdXNlIGJ1dHRvbi4gKi8KIyBpZiAoWG1WZXJzaW9uIDw9IDEwMDIpCglpZiAobW91c2VfbW9kZWxfcG9wdXAoKSkKIyBlbmRpZgoJewoJICAgIGlmIChndWkubWVudV9iZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJICAgIHsKCQlYdFNldEFyZyhhcmdbMF0sIFhtTmJhY2tncm91bmQsIGd1aS5tZW51X2JnX3BpeGVsKTsgbisrOwoJICAgIH0KCSAgICBpZiAoZ3VpLm1lbnVfZmdfcGl4ZWwgIT0gSU5WQUxDT0xPUikKCSAgICB7CgkJWHRTZXRBcmcoYXJnWzFdLCBYbU5mb3JlZ3JvdW5kLCBndWkubWVudV9mZ19waXhlbCk7IG4rKzsKCSAgICB9CgkgICAgbWVudS0+c3VibWVudV9pZCA9IFhtQ3JlYXRlUG9wdXBNZW51KHRleHRBcmVhLCAiY29udGV4dE1lbnUiLAoJCQkJCQkJCSAgICAgIGFyZywgbik7CgkgICAgbWVudS0+aWQgPSAoV2lkZ2V0KTA7Cgl9CglyZXR1cm47CiAgICB9CiNlbmRpZgoKICAgIGlmICghbWVudV9pc19tZW51YmFyKG1lbnUtPm5hbWUpCgkgICAgfHwgKHBhcmVudCAhPSBOVUxMICYmIHBhcmVudC0+c3VibWVudV9pZCA9PSAoV2lkZ2V0KTApKQoJcmV0dXJuOwoKICAgIGxhYmVsID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKiltZW51LT5kbmFtZSwgU1RSSU5HX1RBRyk7CiAgICBpZiAobGFiZWwgPT0gTlVMTCkKCXJldHVybjsKICAgIG1lbnUtPmlkID0gWHRWYUNyZWF0ZVdpZGdldCgic3ViTWVudSIsCgkgICAgeG1DYXNjYWRlQnV0dG9uV2lkZ2V0Q2xhc3MsCgkgICAgKHBhcmVudCA9PSBOVUxMKSA/IG1lbnVCYXIgOiBwYXJlbnQtPnN1Ym1lbnVfaWQsCgkgICAgWG1ObGFiZWxTdHJpbmcsIGxhYmVsLAoJICAgIFhtTm1uZW1vbmljLCBwX3dha1swXSA9PSAnbicgPyBOVUwgOiBtZW51LT5tbmVtb25pYywKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKCSAgICAvKiBzdWJtZW51OiBjb3VudCB0aGUgdGVhcm9mZiBpdGVtIChuZWVkZWQgZm9yIExlc3NUaWYpICovCgkgICAgWG1OcG9zaXRpb25JbmRleCwgaWR4ICsgKHBhcmVudCAhPSBOVUxMCgkJCSAgICYmIHRlYXJvZmZfdmFsID09IChpbnQpWG1URUFSX09GRl9FTkFCTEVEID8gMSA6IDApLAojZW5kaWYKCSAgICBOVUxMKTsKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyhtZW51LT5pZCk7CiAgICBndWlfbW90aWZfbWVudV9mb250bGlzdChtZW51LT5pZCk7CiAgICBYbVN0cmluZ0ZyZWUobGFiZWwpOwoKICAgIGlmIChtZW51LT5pZCA9PSAoV2lkZ2V0KTApCQkvKiBmYWlsZWQgKi8KCXJldHVybjsKCiAgICAvKiBhZGQgYWNjZWxlcmF0b3IgdGV4dCAqLwogICAgZ3VpX21vdGlmX2FkZF9hY3RleHQobWVudSk7CgogICAgc2hlbGwgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJzdWJNZW51U2hlbGwiLAoJeG1NZW51U2hlbGxXaWRnZXRDbGFzcywgbWVudS0+aWQsCglYbU53aWR0aCwgMSwKCVhtTmhlaWdodCwgMSwKCU5VTEwpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHNoZWxsKTsKICAgIG1lbnUtPnN1Ym1lbnVfaWQgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJyb3dDb2x1bW5NZW51IiwKCXhtUm93Q29sdW1uV2lkZ2V0Q2xhc3MsIHNoZWxsLAoJWG1Ocm93Q29sdW1uVHlwZSwgWG1NRU5VX1BVTExET1dOLAoJTlVMTCk7CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnMobWVudS0+c3VibWVudV9pZCk7CgogICAgaWYgKG1lbnUtPnN1Ym1lbnVfaWQgPT0gKFdpZGdldCkwKQkJLyogZmFpbGVkICovCglyZXR1cm47CgojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQogICAgLyogU2V0IHRoZSBjb2xvcnMgZm9yIHRoZSB0ZWFyIG9mZiB3aWRnZXQgKi8KICAgIHRvZ2dsZV90ZWFyb2ZmKG1lbnUtPnN1Ym1lbnVfaWQpOwojZW5kaWYKCiAgICBYdFZhU2V0VmFsdWVzKG1lbnUtPmlkLAoJWG1Oc3ViTWVudUlkLCBtZW51LT5zdWJtZW51X2lkLAoJTlVMTCk7CgogICAgLyoKICAgICAqIFRoZSAiSGVscCIgbWVudSBpcyBhIHNwZWNpYWwgY2FzZSwgYW5kIHNob3VsZCBiZSBwbGFjZWQgYXQgdGhlIGZhcgogICAgICogcmlnaHQgaGFuZCBzaWRlIG9mIHRoZSBtZW51LWJhci4gIEl0J3MgcmVjb2duaXplZCBieSBpdHMgaGlnaCBwcmlvcml0eS4KICAgICAqLwogICAgaWYgKHBhcmVudCA9PSBOVUxMICYmIG1lbnUtPnByaW9yaXR5ID49IDk5OTkpCglYdFZhU2V0VmFsdWVzKG1lbnVCYXIsCgkJWG1ObWVudUhlbHBXaWRnZXQsIG1lbnUtPmlkLAoJCU5VTEwpOwoKICAgIC8qCiAgICAgKiBXaGVuIHdlIGFkZCBhIHRvcC1sZXZlbCBpdGVtIHRvIHRoZSBtZW51IGJhciwgd2UgY2FuIGZpZ3VyZSBvdXQgaG93CiAgICAgKiBoaWdoIHRoZSBtZW51IGJhciBzaG91bGQgYmUuCiAgICAgKi8KICAgIGlmIChwYXJlbnQgPT0gTlVMTCkKCWd1aV9tY2hfY29tcHV0ZV9tZW51X2hlaWdodChtZW51LT5pZCk7Cn0KCgovKgogKiBBZGQgbW5lbW9uaWMgYW5kIGFjY2VsZXJhdG9yIHRleHQgdG8gYSBtZW51IGJ1dHRvbi4KICovCiAgICBzdGF0aWMgdm9pZApndWlfbW90aWZfYWRkX2FjdGV4dChtZW51KQogICAgdmltbWVudV9UCSptZW51Owp7CiAgICBYbVN0cmluZwlsYWJlbDsKCiAgICAvKiBBZGQgYWNjZWxyYXRvciB0ZXh0LCBpZiB0aGVyZSBpcyBvbmUgKi8KICAgIGlmIChtZW51LT5hY3RleHQgIT0gTlVMTCAmJiBtZW51LT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglsYWJlbCA9IFhtU3RyaW5nQ3JlYXRlKChjaGFyICopbWVudS0+YWN0ZXh0LCBTVFJJTkdfVEFHKTsKCWlmIChsYWJlbCA9PSBOVUxMKQoJICAgIHJldHVybjsKCVh0VmFTZXRWYWx1ZXMobWVudS0+aWQsIFhtTmFjY2VsZXJhdG9yVGV4dCwgbGFiZWwsIE5VTEwpOwoJWG1TdHJpbmdGcmVlKGxhYmVsKTsKICAgIH0KfQoKICAgIHZvaWQKZ3VpX21jaF90b2dnbGVfdGVhcm9mZnMoZW5hYmxlKQogICAgaW50CQllbmFibGU7CnsKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKICAgIGlmIChlbmFibGUpCgl0ZWFyb2ZmX3ZhbCA9IChpbnQpWG1URUFSX09GRl9FTkFCTEVEOwogICAgZWxzZQoJdGVhcm9mZl92YWwgPSAoaW50KVhtVEVBUl9PRkZfRElTQUJMRUQ7CiAgICB0b2dnbGVfdGVhcm9mZihtZW51QmFyKTsKICAgIGd1aV9tY2hfcmVjdXJzZV90ZWFyb2Zmcyhyb290X21lbnUpOwojZW5kaWYKfQoKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKLyoKICogU2V0IHRoZSB0ZWFyb2ZmIGZvciBvbmUgbWVudSB3aWRnZXQgb24gb3Igb2ZmLCBhbmQgc2V0IHRoZSBjb2xvciBvZiB0aGUKICogdGVhcm9mZiB3aWRnZXQuCiAqLwogICAgc3RhdGljIHZvaWQKdG9nZ2xlX3RlYXJvZmYod2lkKQogICAgV2lkZ2V0CXdpZDsKewogICAgV2lkZ2V0CXc7CgogICAgWHRWYVNldFZhbHVlcyh3aWQsIFhtTnRlYXJPZmZNb2RlbCwgdGVhcm9mZl92YWwsIE5VTEwpOwogICAgaWYgKHRlYXJvZmZfdmFsID09IChpbnQpWG1URUFSX09GRl9FTkFCTEVECgkgICAgJiYgKHcgPSBYbUdldFRlYXJPZmZDb250cm9sKHdpZCkpICE9IChXaWRnZXQpMCkKCWd1aV9tb3RpZl9tZW51X2NvbG9ycyh3KTsKfQoKICAgIHN0YXRpYyB2b2lkCmd1aV9tY2hfcmVjdXJzZV90ZWFyb2ZmcyhtZW51KQogICAgdmltbWVudV9UCSptZW51Owp7CiAgICB3aGlsZSAobWVudSAhPSBOVUxMKQogICAgewoJaWYgKCFtZW51X2lzX3BvcHVwKG1lbnUtPm5hbWUpKQoJewoJICAgIGlmIChtZW51LT5zdWJtZW51X2lkICE9IChXaWRnZXQpMCkKCQl0b2dnbGVfdGVhcm9mZihtZW51LT5zdWJtZW51X2lkKTsKCSAgICBndWlfbWNoX3JlY3Vyc2VfdGVhcm9mZnMobWVudS0+Y2hpbGRyZW4pOwoJfQoJbWVudSA9IG1lbnUtPm5leHQ7CiAgICB9Cn0KI2VuZGlmCgogICAgaW50Cmd1aV9tY2hfdGV4dF9hcmVhX2V4dHJhX2hlaWdodCgpCnsKICAgIERpbWVuc2lvbglzaGFkb3dIZWlnaHQ7CgogICAgWHRWYUdldFZhbHVlcyh0ZXh0QXJlYUZvcm0sIFhtTnNoYWRvd1RoaWNrbmVzcywgJnNoYWRvd0hlaWdodCwgTlVMTCk7CiAgICByZXR1cm4gc2hhZG93SGVpZ2h0Owp9CgovKgogKiBDb21wdXRlIHRoZSBoZWlnaHQgb2YgdGhlIG1lbnUgYmFyLgogKiBXZSBuZWVkIHRvIGNoZWNrIGFsbCB0aGUgaXRlbXMgZm9yIHRoZWlyIHBvc2l0aW9uIGFuZCBoZWlnaHQsIGZvciB0aGUgY2FzZQogKiB0aGVyZSBhcmUgc2V2ZXJhbCByb3dzLCBhbmQvb3Igc29tZSBjaGFyYWN0ZXJzIGV4dGVuZCBoaWdoZXIgb3IgbG93ZXIuCiAqLwogICAgdm9pZApndWlfbWNoX2NvbXB1dGVfbWVudV9oZWlnaHQoaWQpCiAgICBXaWRnZXQJaWQ7CQkgICAgLyogY2FuIGJlIE5VTEwgd2hlbiBkZWxldGluZyBtZW51ICovCnsKICAgIERpbWVuc2lvbgl5LCBtYXh5OwogICAgRGltZW5zaW9uCW1hcmdpbiwgc2hhZG93OwogICAgdmltbWVudV9UCSptcDsKICAgIHN0YXRpYyBEaW1lbnNpb24JaGVpZ2h0ID0gMjE7CS8qIG5vcm1hbCBoZWlnaHQgb2YgYSBtZW51IGl0ZW0gKi8KCiAgICAvKgogICAgICogR2V0IHRoZSBoZWlnaHQgb2YgdGhlIG5ldyBpdGVtLCBiZWZvcmUgbWFuYWdpbmcgaXQsIGJlY2F1c2UgaXQgd2lsbAogICAgICogc3RpbGwgcmVmbGVjdCB0aGUgZm9udCBzaXplLiAgQWZ0ZXIgbWFuYWdpbmcgaXQgZGVwZW5kcyBvbiB0aGUgbWVudQogICAgICogaGVpZ2h0LCB3aGljaCBpcyB3aGF0IHdlIGp1c3Qgd2FudGVkIHRvIGdldCEuCiAgICAgKi8KICAgIGlmIChpZCAhPSAoV2lkZ2V0KTApCglYdFZhR2V0VmFsdWVzKGlkLCBYbU5oZWlnaHQsICZoZWlnaHQsIE5VTEwpOwoKICAgIC8qIEZpbmQgYW55IG1lbnUgV2lkZ2V0LCB0byBiZSBhYmxlIHRvIGNhbGwgWHRNYW5hZ2VDaGlsZCgpICovCiAgICBlbHNlCglmb3IgKG1wID0gcm9vdF9tZW51OyBtcCAhPSBOVUxMOyBtcCA9IG1wLT5uZXh0KQoJICAgIGlmIChtcC0+aWQgIT0gKFdpZGdldCkwICYmIG1lbnVfaXNfbWVudWJhcihtcC0+bmFtZSkpCgkgICAgewoJCWlkID0gbXAtPmlkOwoJCWJyZWFrOwoJICAgIH0KCiAgICAvKgogICAgICogTm93IG1hbmFnZSB0aGUgbWVudSBpdGVtLCB0byBtYWtlIHRoZW0gYWxsIGJlIHBvc2l0aW9uZWQgKG1ha2VzIGFuCiAgICAgKiBleHRyYSByb3cgd2hlbiBuZWVkZWQsIHJlbW92ZXMgaXQgd2hlbiBub3QgbmVlZGVkKS4KICAgICAqLwogICAgaWYgKGlkICE9IChXaWRnZXQpMCkKCVh0TWFuYWdlQ2hpbGQoaWQpOwoKICAgIC8qCiAgICAgKiBOb3cgZmluZCB0aGUgbWVudSBpdGVtIHRoYXQgaXMgdGhlIGZ1cnRoZXN0IGRvd24sIGFuZCBnZXQgaXQncyBwb3NpdGlvbi4KICAgICAqLwogICAgbWF4eSA9IDA7CiAgICBmb3IgKG1wID0gcm9vdF9tZW51OyBtcCAhPSBOVUxMOyBtcCA9IG1wLT5uZXh0KQogICAgewoJaWYgKG1wLT5pZCAhPSAoV2lkZ2V0KTAgJiYgbWVudV9pc19tZW51YmFyKG1wLT5uYW1lKSkKCXsKCSAgICBYdFZhR2V0VmFsdWVzKG1wLT5pZCwgWG1OeSwgJnksIE5VTEwpOwoJICAgIGlmICh5ID4gbWF4eSkKCQltYXh5ID0geTsKCX0KICAgIH0KCiAgICBYdFZhR2V0VmFsdWVzKG1lbnVCYXIsCglYbU5tYXJnaW5IZWlnaHQsICZtYXJnaW4sCglYbU5zaGFkb3dUaGlja25lc3MsICZzaGFkb3csCglOVUxMKTsKCiAgICAvKgogICAgICogVGhpcyBjb21wdXRhdGlvbiBpcyB0aGUgcmVzdWx0IG9mIHRyaWFsLWFuZC1lcnJvcjoKICAgICAqIG1heHkgPQlUaGUgbWF4aW11bSBwb3NpdGlvbiBvZiBhbiBpdGVtOyByZXF1aXJlZCBmb3Igd2hlbiB0aGVyZSBhcmUKICAgICAqCQl0d28gb3IgbW9yZSByb3dzCiAgICAgKiBoZWlnaHQgPSBoZWlnaHQgb2YgYW4gaXRlbSwgYmVmb3JlIG1hbmFnaW5nIGl0OwlIb3BlZnVsbHkgdGhpcyB3aWxsCiAgICAgKgkJY2hhbmdlIHdpdGggdGhlIGZvbnQgaGVpZ2h0LiAgSW5jbHVkZXMgc2hhZG93LWJvcmRlci4KICAgICAqIHNoYWRvdyA9CXNoYWRvdy1ib3JkZXI7IG11c3QgYmUgc3VidHJhY3RlZCBmcm9tIHRoZSBoZWlnaHQuCiAgICAgKiBtYXJnaW4gPSBtYXJnaW4gYXJvdW5kIHRoZSBtZW51IGJ1dHRvbnM7ICBNdXN0IGJlIGFkZGVkLgogICAgICogQWRkIDQgZm9yIHRoZSB1bmRlcmxpbmluZyBvZiBzaG9ydGN1dCBrZXlzLgogICAgICovCiAgICBndWkubWVudV9oZWlnaHQgPSBtYXh5ICsgaGVpZ2h0IC0gMiAqIHNoYWRvdyArIDIgKiBtYXJnaW4gKyA0OwoKICAgIC8qIFNvbWVob3cgdGhlIG1lbnUgYmFyIGRvZXNuJ3QgcmVzaXplIGF1dG9tYXRpY2FsbHkuICBTZXQgaXQgaGVyZSwKICAgICAqIGV2ZW4gdGhvdWdoIHRoaXMgaXMgYSBjYXRjaCAyMi4gIERvbid0IGRvIHRoaXMgd2hlbiBzdGFydGluZyB1cCwKICAgICAqIHNvbWVob3cgdGhlIG1lbnUgZ2V0cyB2ZXJ5IGhpZ2ggdGhlbi4gKi8KICAgIGlmIChndWkuc2hlbGxfY3JlYXRlZCkKCVh0VmFTZXRWYWx1ZXMobWVudUJhciwgWG1OaGVpZ2h0LCBndWkubWVudV9oZWlnaHQsIE5VTEwpOwp9CgojaWZkZWYgRkVBVF9UT09MQkFSCgovKgogKiBJY29ucyB1c2VkIGJ5IHRoZSB0b29sYmFyIGNvZGUuCiAqLwojaW5jbHVkZSAiZ3VpX3gxMV9wbS5oIgoKc3RhdGljIGludCBjaGVja194cG0gX19BUkdTKChjaGFyX3UgKnBhdGgpKTsKc3RhdGljIGNoYXIgKipnZXRfdG9vbGJhcl9waXhtYXAgX19BUkdTKCh2aW1tZW51X1QgKm1lbnUsIGNoYXIgKipmbmFtZSkpOwpzdGF0aWMgaW50IGFkZF9waXhtYXBfYXJncyBfX0FSR1MoKHZpbW1lbnVfVCAqbWVudSwgQXJnICphcmdzLCBpbnQgbikpOwoKLyoKICogUmVhZCBhbiBYcG0gZmlsZS4gIFJldHVybiBPSyBvciBGQUlMLgogKi8KICAgIHN0YXRpYyBpbnQKY2hlY2tfeHBtKHBhdGgpCiAgICBjaGFyX3UJKnBhdGg7CnsKICAgIFhwbUF0dHJpYnV0ZXMgYXR0cnM7CiAgICBpbnQJCXN0YXR1czsKICAgIFBpeG1hcAltYXNrOwogICAgUGl4bWFwCW1hcDsKCiAgICBhdHRycy52YWx1ZW1hc2sgPSAwOwoKICAgIC8qIENyZWF0ZSB0aGUgInNlbnNpdGl2ZSIgcGl4bWFwICovCiAgICBzdGF0dXMgPSBYcG1SZWFkRmlsZVRvUGl4bWFwKGd1aS5kcHksCgkgICAgUm9vdFdpbmRvdyhndWkuZHB5LCBEZWZhdWx0U2NyZWVuKGd1aS5kcHkpKSwKCSAgICAoY2hhciAqKXBhdGgsICZtYXAsICZtYXNrLCAmYXR0cnMpOwogICAgWHBtRnJlZUF0dHJpYnV0ZXMoJmF0dHJzKTsKCiAgICBpZiAoc3RhdHVzID09IFhwbVN1Y2Nlc3MpCglyZXR1cm4gT0s7CiAgICByZXR1cm4gRkFJTDsKfQoKCi8qCiAqIEFsbG9jYXRlZCBhIHBpeG1hcCBmb3IgdG9vbGJhciBtZW51ICJtZW51Ii4KICogV2hlbiBpdCdzIHRvIGJlIHJlYWQgZnJvbSBhIGZpbGUsICJmbmFtZSIgaXMgc2V0IHRvIHRoZSBmaWxlIG5hbWUKICogKGluIGFsbG9jYXRlZCBtZW1vcnkpLgogKiBSZXR1cm4gYSBibGFuayBwaXhtYXAgaWYgaXQgZmFpbHMuCiAqLwogICAgc3RhdGljIGNoYXIgKioKZ2V0X3Rvb2xiYXJfcGl4bWFwKG1lbnUsIGZuYW1lKQogICAgdmltbWVudV9UCSptZW51OwogICAgY2hhcgkqKmZuYW1lOwp7CiAgICBjaGFyX3UJYnVmW01BWFBBVEhMXTsJCS8qIGJ1ZmZlciBzdG9yaW5nIGV4cGFuZGVkIHBhdGhuYW1lICovCiAgICBjaGFyCSoqeHBtID0gTlVMTDsJCS8qIHhwbSBhcnJheSAqLwogICAgaW50CQlyZXM7CgogICAgKmZuYW1lID0gTlVMTDsKICAgIGJ1ZlswXSA9IE5VTDsJCQkvKiBzdGFydCB3aXRoIE5VTEwgcGF0aCAqLwoKICAgIGlmIChtZW51LT5pY29uZmlsZSAhPSBOVUxMKQogICAgewoJLyogVXNlIHRoZSAiaWNvbj0iICBhcmd1bWVudC4gKi8KCWd1aV9maW5kX2ljb25maWxlKG1lbnUtPmljb25maWxlLCBidWYsICJ4cG0iKTsKCXJlcyA9IGNoZWNrX3hwbShidWYpOwoKCS8qIElmIGl0IGZhaWxlZCwgdHJ5IHVzaW5nIHRoZSBtZW51IG5hbWUuICovCglpZiAocmVzID09IEZBSUwgJiYgZ3VpX2ZpbmRfYml0bWFwKG1lbnUtPm5hbWUsIGJ1ZiwgInhwbSIpID09IE9LKQoJICAgIHJlcyA9IGNoZWNrX3hwbShidWYpOwoJaWYgKHJlcyA9PSBPSykKCXsKCSAgICAqZm5hbWUgPSAoY2hhciAqKXZpbV9zdHJzYXZlKGJ1Zik7CgkgICAgcmV0dXJuIHRiX2JsYW5rX3hwbTsKCX0KICAgIH0KCiAgICBpZiAobWVudS0+aWNvbl9idWlsdGluIHx8IGd1aV9maW5kX2JpdG1hcChtZW51LT5uYW1lLCBidWYsICJ4cG0iKSA9PSBGQUlMKQogICAgewoJaWYgKG1lbnUtPmljb25pZHggPj0gMCAmJiBtZW51LT5pY29uaWR4CgkJICAgPCAoc2l6ZW9mKGJ1aWx0X2luX3BpeG1hcHMpIC8gc2l6ZW9mKGJ1aWx0X2luX3BpeG1hcHNbMF0pKSkKCSAgICB4cG0gPSBidWlsdF9pbl9waXhtYXBzW21lbnUtPmljb25pZHhdOwoJZWxzZQoJICAgIHhwbSA9IHRiX2JsYW5rX3hwbTsKICAgIH0KCiAgICByZXR1cm4geHBtOwp9CgovKgogKiBBZGQgYXJndW1lbnRzIGZvciB0aGUgdG9vbGJhciBwaXhtYXAgdG8gYSBtZW51IGl0ZW0uCiAqLwogICAgc3RhdGljIGludAphZGRfcGl4bWFwX2FyZ3MobWVudSwgYXJncywgbikKICAgIHZpbW1lbnVfVAkqbWVudTsKICAgIEFyZwkJKmFyZ3M7CiAgICBpbnQJCW47CnsKICAgIHZpbV9mcmVlKG1lbnUtPnhwbV9mbmFtZSk7CiAgICBtZW51LT54cG0gPSBnZXRfdG9vbGJhcl9waXhtYXAobWVudSwgJm1lbnUtPnhwbV9mbmFtZSk7CiAgICBpZiAobWVudS0+eHBtID09IE5VTEwpCiAgICB7CglYdFNldEFyZyhhcmdzW25dLCBYbU5sYWJlbFR5cGUsIFhtU1RSSU5HKTsgbisrOwogICAgfQogICAgZWxzZQogICAgewoJaWYgKG1lbnUtPnhwbV9mbmFtZSAhPSBOVUxMKQoJewoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnBpeG1hcEZpbGUsIG1lbnUtPnhwbV9mbmFtZSk7IG4rKzsKCX0KCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnBpeG1hcERhdGEsIG1lbnUtPnhwbSk7IG4rKzsKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxhYmVsTG9jYXRpb24sIFhtQk9UVE9NKTsgbisrOwogICAgfQogICAgcmV0dXJuIG47Cn0KI2VuZGlmIC8qIEZFQVRfVE9PTEJBUiAqLwoKICAgIHZvaWQKZ3VpX21jaF9hZGRfbWVudV9pdGVtKG1lbnUsIGlkeCkKICAgIHZpbW1lbnVfVAkqbWVudTsKICAgIGludAkJaWR4Owp7CiAgICBYbVN0cmluZwlsYWJlbDsKICAgIHZpbW1lbnVfVAkqcGFyZW50ID0gbWVudS0+cGFyZW50OwoKIyBpZmRlZiBFQkNESUMKICAgIG1lbnUtPm1uZW1vbmljID0gMDsKIyBlbmRpZgoKIyBpZiAoWG1WZXJzaW9uIDw9IDEwMDIpCiAgICAvKiBEb24ndCBhZGQgUG9wdXAgbWVudSBpdGVtcyB3aGVuIHRoZSBwb3B1cCBtZW51IGlzbid0IHVzZWQuICovCiAgICBpZiAobWVudV9pc19jaGlsZF9vZl9wb3B1cChtZW51KSAmJiAhbW91c2VfbW9kZWxfcG9wdXAoKSkKCXJldHVybjsKIyBlbmRpZgoKIyBpZmRlZiBGRUFUX1RPT0xCQVIKICAgIGlmIChtZW51X2lzX3Rvb2xiYXIocGFyZW50LT5uYW1lKSkKICAgIHsKCVdpZGdldENsYXNzCXR5cGU7CglYbVN0cmluZwl4bXMgPSBOVUxMOyAgICAvKiBmYWxsYmFjayBsYWJlbCBpZiBwaXhtYXAgbm90IGZvdW5kICovCglpbnQJCW47CglBcmcJCWFyZ3NbMThdOwoKCW4gPSAwOwoJaWYgKG1lbnVfaXNfc2VwYXJhdG9yKG1lbnUtPm5hbWUpKQoJewoJICAgIGNoYXIJKmNwOwoJICAgIERpbWVuc2lvbgl3aWQ7CgoJICAgIC8qCgkgICAgICogQSBzZXBhcmF0b3IgaGFzIHRoZSBmb3JtYXQgIi1zZXAlZFs6JWRdLSIuIFRoZSBvcHRpb25hbCA6JWQgaXMKCSAgICAgKiBhIHdpZHRoIHNwZWNpZmllci4gSWYgbm8gd2lkdGggaXMgc3BlY2lmaWVkIHRoZW4gd2UgY2hvb3NlIG9uZS4KCSAgICAgKi8KCSAgICBjcCA9IChjaGFyICopdmltX3N0cmNocihtZW51LT5uYW1lLCAnOicpOwoJICAgIGlmIChjcCAhPSBOVUxMKQoJCXdpZCA9IChEaW1lbnNpb24pYXRvaSgrK2NwKTsKCSAgICBlbHNlCgkJd2lkID0gNDsKCiNpZiAwCgkgICAgLyogV2UgYmV0dGVyIHVzZSBhIEZvcm1XaWRnZXQgaGVyZSwgc2luY2UgaXQncyBmYXIgbW9yZQoJICAgICAqIGZsZXhpYmxlIGluIHRlcm1zIG9mIHNpemUuICAqLwoJICAgIHR5cGUgPSB4bUZvcm1XaWRnZXRDbGFzczsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU53aWR0aCwgd2lkKTsgbisrOwojZWxzZQoJICAgIHR5cGUgPSB4bVNlcGFyYXRvcldpZGdldENsYXNzOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTndpZHRoLCB3aWQpOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObWluV2lkdGgsIHdpZCk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5vcmllbnRhdGlvbiwgWG1WRVJUSUNBTCk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5zZXBhcmF0b3JUeXBlLCBYbVNIQURPV19FVENIRURfSU4pOyBuKys7CiNlbmRpZgoJfQoJZWxzZQoJewoJICAgIC8qIFdpdGhvdXQgc2hhZG93cyBvbmUgY2FuJ3Qgc2Vuc2Ugd2hhdGV2ZXIgdGhlIGJ1dHRvbiBoYXMgYmVlbgoJICAgICAqIHByZXNzZWQgb3Igbm90ISBIb3dldmVyIHdlIHdhbid0IHRvIHNhdmUgYSBiaXQgb2Ygc3BhY2UuLi4KCSAgICAgKiBOZWVkIHRoZSBoaWdobGlnaHRUaGlja25lc3MgdG8gc2VlIHRoZSBmb2N1cy4KCSAgICAgKi8KCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5oaWdobGlnaHRUaGlja25lc3MsIDEpOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OaGlnaGxpZ2h0T25FbnRlciwgVHJ1ZSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5tYXJnaW5XaWR0aCwgMCk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5tYXJnaW5IZWlnaHQsIDApOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdHJhdmVyc2FsT24sIEZhbHNlKTsgbisrOwoJICAgIC8qIFNldCB0aGUgbGFiZWwgaGVyZSwgc28gdGhhdCB3ZSBjYW4gc3dpdGNoIGJldHdlZW4gaWNvbnMvdGV4dAoJICAgICAqIGJ5IGNoYW5naW5nIHRoZSBYbU5sYWJlbFR5cGUgcmVzb3VyY2UuICovCgkgICAgeG1zID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKiltZW51LT5kbmFtZSwgU1RSSU5HX1RBRyk7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGFiZWxTdHJpbmcsIHhtcyk7IG4rKzsKCgkgICAgbiA9IGFkZF9waXhtYXBfYXJncyhtZW51LCBhcmdzLCBuKTsKCgkgICAgdHlwZSA9IHhtRW5oYW5jZWRCdXR0b25XaWRnZXRDbGFzczsKCX0KCglYdFNldEFyZyhhcmdzW25dLCBYbU5wb3NpdGlvbkluZGV4LCBpZHgpOyBuKys7CglpZiAobWVudS0+aWQgPT0gTlVMTCkKCXsKCSAgICBtZW51LT5pZCA9IFh0Q3JlYXRlTWFuYWdlZFdpZGdldCgoY2hhciAqKW1lbnUtPmRuYW1lLAoJCQl0eXBlLCB0b29sQmFyLCBhcmdzLCBuKTsKCSAgICBpZiAobWVudS0+aWQgIT0gTlVMTCAmJiB0eXBlID09IHhtRW5oYW5jZWRCdXR0b25XaWRnZXRDbGFzcykKCSAgICB7CgkJWHRBZGRDYWxsYmFjayhtZW51LT5pZCwKCQkJWG1OYWN0aXZhdGVDYWxsYmFjaywgZ3VpX3gxMV9tZW51X2NiLCBtZW51KTsKIyBpZmRlZiBGRUFUX0ZPT1RFUgoJCVh0QWRkRXZlbnRIYW5kbGVyKG1lbnUtPmlkLCBFbnRlcldpbmRvd01hc2ssIEZhbHNlLAoJCQl0b29sYmFyYnV0dG9uX2VudGVyX2NiLCBtZW51KTsKCQlYdEFkZEV2ZW50SGFuZGxlcihtZW51LT5pZCwgTGVhdmVXaW5kb3dNYXNrLCBGYWxzZSwKCQkJdG9vbGJhcmJ1dHRvbl9sZWF2ZV9jYiwgbWVudSk7CiMgZW5kaWYKCSAgICB9Cgl9CgllbHNlCgkgICAgWHRTZXRWYWx1ZXMobWVudS0+aWQsIGFyZ3MsIG4pOwoJaWYgKHhtcyAhPSBOVUxMKQoJICAgIFhtU3RyaW5nRnJlZSh4bXMpOwoKI2lmZGVmIEZFQVRfQkVWQUwKCWd1aV9tY2hfbWVudV9zZXRfdGlwKG1lbnUpOwojZW5kaWYKCgltZW51LT5wYXJlbnQgPSBwYXJlbnQ7CgltZW51LT5zdWJtZW51X2lkID0gTlVMTDsKCS8qIFdoZW4gYWRkaW5nIGZpcnN0IGl0ZW0gdG8gdG9vbGJhciBpdCBtaWdodCBoYXZlIHRvIGJlIGVuYWJsZWQgLiovCglpZiAoIVh0SXNNYW5hZ2VkKFh0UGFyZW50KHRvb2xCYXIpKQoJCSAgICAmJiB2aW1fc3RyY2hyKHBfZ28sIEdPX1RPT0xCQVIpICE9IE5VTEwpCgkgICAgZ3VpX21jaF9zaG93X3Rvb2xiYXIoVFJVRSk7CglndWkudG9vbGJhcl9oZWlnaHQgPSBndWlfbWNoX2NvbXB1dGVfdG9vbGJhcl9oZWlnaHQoKTsKCXJldHVybjsKICAgIH0gLyogdG9vbGJhciBtZW51IGl0ZW0gKi8KIyBlbmRpZgoKICAgIC8qIE5vIHBhcmVudCwgbXVzdCBiZSBhIG5vbi1tZW51YmFyIG1lbnUgKi8KICAgIGlmIChwYXJlbnQtPnN1Ym1lbnVfaWQgPT0gKFdpZGdldCkwKQoJcmV0dXJuOwoKICAgIG1lbnUtPnN1Ym1lbnVfaWQgPSAoV2lkZ2V0KTA7CgogICAgLyogQWRkIG1lbnUgc2VwYXJhdG9yICovCiAgICBpZiAobWVudV9pc19zZXBhcmF0b3IobWVudS0+bmFtZSkpCiAgICB7CgltZW51LT5pZCA9IFh0VmFDcmVhdGVXaWRnZXQoInN1Yk1lbnUiLAoJCXhtU2VwYXJhdG9yR2FkZ2V0Q2xhc3MsIHBhcmVudC0+c3VibWVudV9pZCwKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKCQkvKiBjb3VudCB0aGUgdGVhcm9mZiBpdGVtIChuZWVkZWQgZm9yIExlc3NUaWYpICovCgkJWG1OcG9zaXRpb25JbmRleCwgaWR4ICsgKHRlYXJvZmZfdmFsID09IChpbnQpWG1URUFSX09GRl9FTkFCTEVECgkJCQkJCQkJICAgICA/IDEgOiAwKSwKI2VuZGlmCgkJTlVMTCk7CglndWlfbW90aWZfbWVudV9jb2xvcnMobWVudS0+aWQpOwoJcmV0dXJuOwogICAgfQoKICAgIGxhYmVsID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKiltZW51LT5kbmFtZSwgU1RSSU5HX1RBRyk7CiAgICBpZiAobGFiZWwgPT0gTlVMTCkKCXJldHVybjsKICAgIG1lbnUtPmlkID0gWHRWYUNyZWF0ZVdpZGdldCgic3ViTWVudSIsCgl4bVB1c2hCdXR0b25XaWRnZXRDbGFzcywgcGFyZW50LT5zdWJtZW51X2lkLAoJWG1ObGFiZWxTdHJpbmcsIGxhYmVsLAoJWG1ObW5lbW9uaWMsIG1lbnUtPm1uZW1vbmljLAojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJLyogY291bnQgdGhlIHRlYXJvZmYgaXRlbSAobmVlZGVkIGZvciBMZXNzVGlmKSAqLwoJWG1OcG9zaXRpb25JbmRleCwgaWR4ICsgKHRlYXJvZmZfdmFsID09IChpbnQpWG1URUFSX09GRl9FTkFCTEVECgkJCQkJCQkJICAgICA/IDEgOiAwKSwKI2VuZGlmCglOVUxMKTsKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyhtZW51LT5pZCk7CiAgICBndWlfbW90aWZfbWVudV9mb250bGlzdChtZW51LT5pZCk7CiAgICBYbVN0cmluZ0ZyZWUobGFiZWwpOwoKICAgIGlmIChtZW51LT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglYdEFkZENhbGxiYWNrKG1lbnUtPmlkLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLCBndWlfeDExX21lbnVfY2IsCgkJKFh0UG9pbnRlciltZW51KTsKCS8qIGFkZCBhY2NlbGVyYXRvciB0ZXh0ICovCglndWlfbW90aWZfYWRkX2FjdGV4dChtZW51KTsKICAgIH0KfQoKI2lmIChYbVZlcnNpb24gPD0gMTAwMikgfHwgZGVmaW5lZChQUk9UTykKLyoKICogVGhpcyBmdW5jdGlvbiB3aWxsIGRlc3Ryb3kvY3JlYXRlIHRoZSBwb3B1cCBtZW51cyBkeW5hbWljYWxseSwKICogYWNjb3JkaW5nIHRvIHRoZSB2YWx1ZSBvZiAnbW91c2Vtb2RlbCcuCiAqIFRoaXMgd2lsbCBmaXggdGhlICJyaWdodCBtb3VzZSBidXR0b24gZnJlZXplIiB0aGF0IG9jY3VycyB3aGVuCiAqIHRoZXJlIGV4aXN0cyBhIHBvcHVwIG1lbnUgYnV0IGl0IGlzbid0IG1hbmFnZWQuCiAqLwogICAgdm9pZApndWlfbW90aWZfdXBkYXRlX21vdXNlbW9kZWwobWVudSkKICAgIHZpbW1lbnVfVAkqbWVudTsKewogICAgaW50CQlpZHggPSAwOwoKICAgIC8qIFdoZW4gR1VJIGhhc24ndCBzdGFydGVkIHRoZSBtZW51cyBoYXZlIG5vdCBiZWVuIGNyZWF0ZWQuICovCiAgICBpZiAoIWd1aS5pbl91c2UpCiAgICAgIHJldHVybjsKCiAgICB3aGlsZSAobWVudSkKICAgIHsKICAgICAgaWYgKG1lbnUtPmNoaWxkcmVuICE9IE5VTEwpCiAgICAgIHsKCSAgaWYgKG1lbnVfaXNfcG9wdXAobWVudS0+bmFtZSkpCgkgIHsKCSAgICAgIGlmIChtb3VzZV9tb2RlbF9wb3B1cCgpKQoJICAgICAgewoJCSAgLyogUG9wdXAgbWVudSB3aWxsIGJlIHVzZWQuICBDcmVhdGUgdGhlIHBvcHVwIG1lbnVzLiAqLwoJCSAgZ3VpX21jaF9hZGRfbWVudShtZW51LCBpZHgpOwoJCSAgZ3VpX21vdGlmX3VwZGF0ZV9tb3VzZW1vZGVsKG1lbnUtPmNoaWxkcmVuKTsKCSAgICAgIH0KCSAgICAgIGVsc2UKCSAgICAgIHsKCQkgIC8qIFBvcHVwIG1lbnUgd2lsbCBub3QgYmUgdXNlZC4gIERlc3Ryb3kgdGhlIHBvcHVwIG1lbnVzLiAqLwoJCSAgZ3VpX21vdGlmX3VwZGF0ZV9tb3VzZW1vZGVsKG1lbnUtPmNoaWxkcmVuKTsKCQkgIGd1aV9tY2hfZGVzdHJveV9tZW51KG1lbnUpOwoJICAgICAgfQoJICB9CiAgICAgIH0KICAgICAgZWxzZSBpZiAobWVudV9pc19jaGlsZF9vZl9wb3B1cChtZW51KSkKICAgICAgewoJICBpZiAobW91c2VfbW9kZWxfcG9wdXAoKSkKCSAgICAgIGd1aV9tY2hfYWRkX21lbnVfaXRlbShtZW51LCBpZHgpOwoJICBlbHNlCgkgICAgICBndWlfbWNoX2Rlc3Ryb3lfbWVudShtZW51KTsKICAgICAgfQogICAgICBtZW51ID0gbWVudS0+bmV4dDsKICAgICAgKytpZHg7CiAgICB9Cn0KI2VuZGlmCgogICAgdm9pZApndWlfbWNoX25ld19tZW51X2NvbG9ycygpCnsKICAgIGlmIChtZW51QmFyID09IChXaWRnZXQpMCkKCXJldHVybjsKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyhtZW51QmFyKTsKI2lmZGVmIEZFQVRfVE9PTEJBUgogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHRvb2xCYXJGcmFtZSk7CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnModG9vbEJhcik7CiNlbmRpZgoKICAgIHN1Ym1lbnVfY2hhbmdlKHJvb3RfbWVudSwgVFJVRSk7Cn0KCiAgICB2b2lkCmd1aV9tY2hfbmV3X21lbnVfZm9udCgpCnsKICAgIGlmIChtZW51QmFyID09IChXaWRnZXQpMCkKCXJldHVybjsKICAgIHN1Ym1lbnVfY2hhbmdlKHJvb3RfbWVudSwgRkFMU0UpOwogICAgewoJRGltZW5zaW9uICAgaGVpZ2h0OwoJUG9zaXRpb24gdywgaDsKCglYdFZhR2V0VmFsdWVzKG1lbnVCYXIsIFhtTmhlaWdodCwgJmhlaWdodCwgTlVMTCk7CglndWkubWVudV9oZWlnaHQgPSBoZWlnaHQ7CgoJWHRWYUdldFZhbHVlcyh2aW1TaGVsbCwgWHROd2lkdGgsICZ3LCBYdE5oZWlnaHQsICZoLCBOVUxMKTsKCWd1aV9yZXNpemVfc2hlbGwodywgaAojaWZkZWYgRkVBVF9YSU0KCQktIHhpbV9nZXRfc3RhdHVzX2FyZWFfaGVpZ2h0KCkKI2VuZGlmCgkJICAgICApOwogICAgfQogICAgZ3VpX3NldF9zaGVsbHNpemUoRkFMU0UsIFRSVUUpOwogICAgdWlfbmV3X3NoZWxsc2l6ZSgpOwp9CgojaWYgZGVmaW5lZChGRUFUX0JFVkFMKSB8fCBkZWZpbmVkKFBST1RPKQogICAgdm9pZApndWlfbWNoX25ld190b29sdGlwX2ZvbnQoKQp7CiMgaWZkZWYgRkVBVF9UT09MQkFSCiAgICB2aW1tZW51X1QgICAqbWVudTsKCiAgICBpZiAodG9vbEJhciA9PSAoV2lkZ2V0KTApCglyZXR1cm47CgogICAgbWVudSA9IGd1aV9maW5kX21lbnUoKGNoYXJfdSAqKSJUb29sQmFyIik7CiAgICBpZiAobWVudSAhPSBOVUxMKQoJc3VibWVudV9jaGFuZ2UobWVudSwgRkFMU0UpOwojIGVuZGlmCn0KCiAgICB2b2lkCmd1aV9tY2hfbmV3X3Rvb2x0aXBfY29sb3JzKCkKewojIGlmZGVmIEZFQVRfVE9PTEJBUgogICAgdmltbWVudV9UICAgKnRvb2xiYXI7CgogICAgaWYgKHRvb2xCYXIgPT0gKFdpZGdldCkwKQoJcmV0dXJuOwoKICAgIHRvb2xiYXIgPSBndWlfZmluZF9tZW51KChjaGFyX3UgKikiVG9vbEJhciIpOwogICAgaWYgKHRvb2xiYXIgIT0gTlVMTCkKCXN1Ym1lbnVfY2hhbmdlKHRvb2xiYXIsIFRSVUUpOwojIGVuZGlmCn0KI2VuZGlmCgogICAgc3RhdGljIHZvaWQKc3VibWVudV9jaGFuZ2UobWVudSwgY29sb3JzKQogICAgdmltbWVudV9UCSptZW51OwogICAgaW50CQljb2xvcnM7CQkvKiBUUlVFIGZvciBjb2xvcnMsIEZBTFNFIGZvciBmb250ICovCnsKICAgIHZpbW1lbnVfVAkqbXA7CgogICAgZm9yIChtcCA9IG1lbnU7IG1wICE9IE5VTEw7IG1wID0gbXAtPm5leHQpCiAgICB7CglpZiAobXAtPmlkICE9IChXaWRnZXQpMCkKCXsKCSAgICBpZiAoY29sb3JzKQoJICAgIHsKCQlndWlfbW90aWZfbWVudV9jb2xvcnMobXAtPmlkKTsKI2lmZGVmIEZFQVRfVE9PTEJBUgoJCS8qIEZvciBhIHRvb2xiYXIgaXRlbTogRnJlZSB0aGUgcGl4bWFwIGFuZCBhbGxvY2F0ZSBhIG5ldyBvbmUsCgkJICogc28gdGhhdCB0aGUgYmFja2dyb3VuZCBjb2xvciBpcyByaWdodC4gKi8KCQlpZiAobXAtPnhwbSAhPSBOVUxMKQoJCXsKCQkgICAgaW50CQluID0gMDsKCQkgICAgQXJnCQlhcmdzWzE4XTsKCgkJICAgIG4gPSBhZGRfcGl4bWFwX2FyZ3MobXAsIGFyZ3MsIG4pOwoJCSAgICBYdFNldFZhbHVlcyhtcC0+aWQsIGFyZ3MsIG4pOwoJCX0KIyBpZmRlZiBGRUFUX0JFVkFMCgkJLyogSWYgd2UgaGF2ZSBhIHRvb2x0aXAsIHRoZW4gd2UgbmVlZCB0byBjaGFuZ2UgaXQncyBmb250ICovCgkJaWYgKG1wLT50aXAgIT0gTlVMTCkKCQl7CgkJICAgIEFyZyBhcmdzWzJdOwoKCQkgICAgYXJnc1swXS5uYW1lID0gWG1OYmFja2dyb3VuZDsKCQkgICAgYXJnc1swXS52YWx1ZSA9IGd1aS50b29sdGlwX2JnX3BpeGVsOwoJCSAgICBhcmdzWzFdLm5hbWUgPSBYbU5mb3JlZ3JvdW5kOwoJCSAgICBhcmdzWzFdLnZhbHVlID0gZ3VpLnRvb2x0aXBfZmdfcGl4ZWw7CgkJICAgIFh0U2V0VmFsdWVzKG1wLT50aXAtPmJhbGxvb25MYWJlbCwgJmFyZ3NbMF0sIFh0TnVtYmVyKGFyZ3MpKTsKCQl9CiMgZW5kaWYKI2VuZGlmCgkgICAgfQoJICAgIGVsc2UKCSAgICB7CgkJZ3VpX21vdGlmX21lbnVfZm9udGxpc3QobXAtPmlkKTsKI2lmZGVmIEZFQVRfQkVWQUwKCQkvKiBJZiB3ZSBoYXZlIGEgdG9vbHRpcCwgdGhlbiB3ZSBuZWVkIHRvIGNoYW5nZSBpdCdzIGZvbnQgKi8KCQlpZiAobXAtPnRpcCAhPSBOVUxMKQoJCXsKCQkgICAgQXJnIGFyZ3NbMV07CgoJCSAgICBhcmdzWzBdLm5hbWUgPSBYbU5mb250TGlzdDsKCQkgICAgYXJnc1swXS52YWx1ZSA9IChYdEFyZ1ZhbClndWlfbW90aWZfZm9udHNldDJmb250bGlzdCgKCQkJCQkJICAgICZndWkudG9vbHRpcF9mb250c2V0KTsKCQkgICAgWHRTZXRWYWx1ZXMobXAtPnRpcC0+YmFsbG9vbkxhYmVsLCAmYXJnc1swXSwgWHROdW1iZXIoYXJncykpOwoJCX0KI2VuZGlmCgkgICAgfQoJfQoKCWlmIChtcC0+Y2hpbGRyZW4gIT0gTlVMTCkKCXsKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKCSAgICAvKiBTZXQgdGhlIGNvbG9ycy9mb250IGZvciB0aGUgdGVhciBvZmYgd2lkZ2V0ICovCgkgICAgaWYgKG1wLT5zdWJtZW51X2lkICE9IChXaWRnZXQpMCkKCSAgICB7CgkJaWYgKGNvbG9ycykKCQkgICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKG1wLT5zdWJtZW51X2lkKTsKCQllbHNlCgkJICAgIGd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KG1wLT5zdWJtZW51X2lkKTsKCQl0b2dnbGVfdGVhcm9mZihtcC0+c3VibWVudV9pZCk7CgkgICAgfQojZW5kaWYKCSAgICAvKiBTZXQgdGhlIGNvbG9ycyBmb3IgdGhlIGNoaWxkcmVuICovCgkgICAgc3VibWVudV9jaGFuZ2UobXAtPmNoaWxkcmVuLCBjb2xvcnMpOwoJfQogICAgfQp9CgovKgogKiBEZXN0cm95IHRoZSBtYWNoaW5lIHNwZWNpZmljIG1lbnUgd2lkZ2V0LgogKi8KICAgIHZvaWQKZ3VpX21jaF9kZXN0cm95X21lbnUobWVudSkKICAgIHZpbW1lbnVfVAkqbWVudTsKewogICAgLyogUGxlYXNlIGJlIHN1cmUgdG8gZGVzdHJveSB0aGUgcGFyZW50IHdpZGdldCBmaXJzdCAoaS5lLiBtZW51LT5pZCkuCiAgICAgKiBPbiB0aGUgb3RoZXIgaGFuZCwgcHJvYmxlbXMgaGF2ZSBiZWVuIHJlcG9ydGVkIHRoYXQgdGhlIHN1Ym1lbnUgbXVzdCBiZQogICAgICogZGVsZXRlZCBmaXJzdC4uLgogICAgICoKICAgICAqIFRoaXMgY29kZSBzaG91bGQgYmUgYmFzaWNhbGx5IGlkZW50aWNhbCB0byB0aGF0IGluIHRoZSBmaWxlIGd1aV9hdGhlbmEuYwogICAgICogYmVjYXVzZSB0aGV5IGFyZSBib3RoIFh0IGJhc2VkLgogICAgICovCiAgICBpZiAobWVudS0+c3VibWVudV9pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglYdERlc3Ryb3lXaWRnZXQobWVudS0+c3VibWVudV9pZCk7CgltZW51LT5zdWJtZW51X2lkID0gKFdpZGdldCkwOwogICAgfQoKICAgIGlmIChtZW51LT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglXaWRnZXQJICAgIHBhcmVudDsKCglwYXJlbnQgPSBYdFBhcmVudChtZW51LT5pZCk7CiNpZiBkZWZpbmVkKEZFQVRfVE9PTEJBUikgJiYgZGVmaW5lZChGRUFUX0JFVkFMKQoJaWYgKHBhcmVudCA9PSB0b29sQmFyICYmIG1lbnUtPnRpcCAhPSBOVUxMKQoJewoJICAgIC8qIFdlIHRyeSB0byBkZXN0cm95IHRoaXMgYmVmb3JlIHRoZSBhY3R1YWwgbWVudSwgYmVjYXVzZSB0aGVyZSBhcmUKCSAgICAgKiBjYWxsYmFja3MsIGV0Yy4gdGhhdCB3aWxsIGJlIHVucmVnaXN0ZXJlZCBkdXJpbmcgdGhlIHRvb2x0aXAKCSAgICAgKiBkZXN0cnVjdGlvbi4KCSAgICAgKgoJICAgICAqIElmIHlvdSBjYWxsICJndWlfbWNoX2Rlc3Ryb3lfYmV2YWxfYXJlYSgpIiBhZnRlciBkZXN0cm95aW5nCgkgICAgICogbWVudS0+aWQsIHRoZW4gdGhlIHRvb2x0aXAncyB3aW5kb3cgd2lsbCBoYXZlIGFscmVhZHkgYmVlbgoJICAgICAqIGRlYWxsb2NhdGVkIGJ5IFh0LCBhbmQgdW5rbm93biBiZWhhdmlvdXIgd2lsbCBlbnN1ZSAocHJvYmFibHkKCSAgICAgKiBhIGNvcmUgZHVtcCkuCgkgICAgICovCgkgICAgZ3VpX21jaF9kZXN0cm95X2JldmFsX2FyZWEobWVudS0+dGlwKTsKCSAgICBtZW51LT50aXAgPSBOVUxMOwoJfQojZW5kaWYKCVh0RGVzdHJveVdpZGdldChtZW51LT5pZCk7CgltZW51LT5pZCA9IChXaWRnZXQpMDsKCWlmIChwYXJlbnQgPT0gbWVudUJhcikKCSAgICBndWlfbWNoX2NvbXB1dGVfbWVudV9oZWlnaHQoKFdpZGdldCkwKTsKI2lmZGVmIEZFQVRfVE9PTEJBUgoJZWxzZSBpZiAocGFyZW50ID09IHRvb2xCYXIpCgl7CgkgICAgQ2FyZGluYWwgICAgbnVtX2NoaWxkcmVuOwoKCSAgICAvKiBXaGVuIHJlbW92aW5nIGxhc3QgdG9vbGJhciBpdGVtLCBkb24ndCBkaXNwbGF5IHRoZSB0b29sYmFyLiAqLwoJICAgIFh0VmFHZXRWYWx1ZXModG9vbEJhciwgWG1ObnVtQ2hpbGRyZW4sICZudW1fY2hpbGRyZW4sIE5VTEwpOwoJICAgIGlmIChudW1fY2hpbGRyZW4gPT0gMCkKCQlndWlfbWNoX3Nob3dfdG9vbGJhcihGQUxTRSk7CgkgICAgZWxzZQoJCWd1aS50b29sYmFyX2hlaWdodCA9IGd1aV9tY2hfY29tcHV0ZV90b29sYmFyX2hlaWdodCgpOwoJfQojZW5kaWYKICAgIH0KfQoKLyogQVJHU1VTRUQgKi8KICAgIHZvaWQKZ3VpX21jaF9zaG93X3BvcHVwbWVudShtZW51KQogICAgdmltbWVudV9UICptZW51Owp7CiNpZmRlZiBNT1RJRl9QT1BVUAogICAgWG1NZW51UG9zaXRpb24obWVudS0+c3VibWVudV9pZCwgZ3VpX3gxMV9nZXRfbGFzdF9tb3VzZV9ldmVudCgpKTsKICAgIFh0TWFuYWdlQ2hpbGQobWVudS0+c3VibWVudV9pZCk7CiNlbmRpZgp9CgojZW5kaWYgLyogRkVBVF9NRU5VICovCgovKgogKiBTZXQgdGhlIG1lbnUgYW5kIHNjcm9sbGJhciBjb2xvcnMgdG8gdGhlaXIgZGVmYXVsdCB2YWx1ZXMuCiAqLwogICAgdm9pZApndWlfbWNoX2RlZl9jb2xvcnMoKQp7CiAgICBpZiAoZ3VpLmluX3VzZSkKICAgIHsKCS8qIFVzZSB0aGUgdmFsdWVzIHNhdmVkIHdoZW4gc3RhcnRpbmcgdXAuICBUaGVzZSBzaG91bGQgY29tZSBmcm9tIHRoZQoJICogd2luZG93IG1hbmFnZXIgb3IgYSByZXNvdXJjZXMgZmlsZS4gKi8KCWd1aS5tZW51X2ZnX3BpeGVsID0gZ3VpLm1lbnVfZGVmX2ZnX3BpeGVsOwoJZ3VpLm1lbnVfYmdfcGl4ZWwgPSBndWkubWVudV9kZWZfYmdfcGl4ZWw7CglndWkuc2Nyb2xsX2ZnX3BpeGVsID0gZ3VpLnNjcm9sbF9kZWZfZmdfcGl4ZWw7CglndWkuc2Nyb2xsX2JnX3BpeGVsID0gZ3VpLnNjcm9sbF9kZWZfYmdfcGl4ZWw7CiNpZmRlZiBGRUFUX0JFVkFMCglndWkudG9vbHRpcF9mZ19waXhlbCA9CgkJCWd1aV9nZXRfY29sb3IoKGNoYXJfdSAqKWd1aS5yc3JjX3Rvb2x0aXBfZmdfbmFtZSk7CglndWkudG9vbHRpcF9iZ19waXhlbCA9CgkJCWd1aV9nZXRfY29sb3IoKGNoYXJfdSAqKWd1aS5yc3JjX3Rvb2x0aXBfYmdfbmFtZSk7CiNlbmRpZgogICAgfQp9CgoKLyoKICogU2Nyb2xsYmFyIHN0dWZmLgogKi8KCiAgICB2b2lkCmd1aV9tY2hfc2V0X3Njcm9sbGJhcl90aHVtYihzYiwgdmFsLCBzaXplLCBtYXgpCiAgICBzY3JvbGxiYXJfVCAqc2I7CiAgICBsb25nCXZhbDsKICAgIGxvbmcJc2l6ZTsKICAgIGxvbmcJbWF4Owp7CiAgICBpZiAoc2ItPmlkICE9IChXaWRnZXQpMCkKCVh0VmFTZXRWYWx1ZXMoc2ItPmlkLAoJCSAgWG1OdmFsdWUsIHZhbCwKCQkgIFhtTnNsaWRlclNpemUsIHNpemUsCgkJICBYbU5wYWdlSW5jcmVtZW50LCAoc2l6ZSA+IDIgPyBzaXplIC0gMiA6IDEpLAoJCSAgWG1ObWF4aW11bSwgbWF4ICsgMSwJICAgIC8qIE1vdGlmIGhhcyBtYXggb25lIHBhc3QgdGhlIGVuZCAqLwoJCSAgTlVMTCk7Cn0KCiAgICB2b2lkCmd1aV9tY2hfc2V0X3Njcm9sbGJhcl9wb3Moc2IsIHgsIHksIHcsIGgpCiAgICBzY3JvbGxiYXJfVCAqc2I7CiAgICBpbnQJCXg7CiAgICBpbnQJCXk7CiAgICBpbnQJCXc7CiAgICBpbnQJCWg7CnsKICAgIGlmIChzYi0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJaWYgKHNiLT50eXBlID09IFNCQVJfTEVGVCB8fCBzYi0+dHlwZSA9PSBTQkFSX1JJR0hUKQoJewoJICAgIGlmICh5ID09IDApCgkJaCAtPSBndWkuYm9yZGVyX29mZnNldDsKCSAgICBlbHNlCgkJeSAtPSBndWkuYm9yZGVyX29mZnNldDsKCSAgICBYdFZhU2V0VmFsdWVzKHNiLT5pZCwKCQkJICBYbU50b3BPZmZzZXQsIHksCgkJCSAgWG1OYm90dG9tT2Zmc2V0LCAteSAtIGgsCgkJCSAgWG1Od2lkdGgsIHcsCgkJCSAgTlVMTCk7Cgl9CgllbHNlCgkgICAgWHRWYVNldFZhbHVlcyhzYi0+aWQsCgkJCSAgWG1OdG9wT2Zmc2V0LCB5LAoJCQkgIFhtTmxlZnRPZmZzZXQsIHgsCgkJCSAgWG1OcmlnaHRPZmZzZXQsIGd1aS53aGljaF9zY3JvbGxiYXJzW1NCQVJfUklHSFRdCgkJCQkJCSAgICA/IGd1aS5zY3JvbGxiYXJfd2lkdGggOiAwLAoJCQkgIFhtTmhlaWdodCwgaCwKCQkJICBOVUxMKTsKCVh0TWFuYWdlQ2hpbGQoc2ItPmlkKTsKICAgIH0KfQoKICAgIHZvaWQKZ3VpX21jaF9lbmFibGVfc2Nyb2xsYmFyKHNiLCBmbGFnKQogICAgc2Nyb2xsYmFyX1QgKnNiOwogICAgaW50CQlmbGFnOwp7CiAgICBBcmcJCWFyZ3NbMTZdOwogICAgaW50CQluOwoKICAgIGlmIChzYi0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJbiA9IDA7CglpZiAoZmxhZykKCXsKCSAgICBzd2l0Y2ggKHNiLT50eXBlKQoJICAgIHsKCQljYXNlIFNCQVJfTEVGVDoKCQkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdE9mZnNldCwgZ3VpLnNjcm9sbGJhcl93aWR0aCk7IG4rKzsKCQkgICAgYnJlYWs7CgoJCWNhc2UgU0JBUl9SSUdIVDoKCQkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OcmlnaHRPZmZzZXQsIGd1aS5zY3JvbGxiYXJfd2lkdGgpOyBuKys7CgkJICAgIGJyZWFrOwoKCQljYXNlIFNCQVJfQk9UVE9NOgoJCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21PZmZzZXQsIGd1aS5zY3JvbGxiYXJfaGVpZ2h0KTtuKys7CgkJICAgIGJyZWFrOwoJICAgIH0KCSAgICBYdFNldFZhbHVlcyh0ZXh0QXJlYSwgYXJncywgbik7CgkgICAgWHRNYW5hZ2VDaGlsZChzYi0+aWQpOwoJfQoJZWxzZQoJewoJICAgIGlmICghZ3VpLndoaWNoX3Njcm9sbGJhcnNbc2ItPnR5cGVdKQoJICAgIHsKCQkvKiBUaGUgc2Nyb2xsYmFycyBvZiB0aGlzIHR5cGUgYXJlIGFsbCBkaXNhYmxlZCwgYWRqdXN0IHRoZQoJCSAqIHRleHRBcmVhIGF0dGFjaG1lbnQgb2Zmc2V0LiAqLwoJCXN3aXRjaCAoc2ItPnR5cGUpCgkJewoJCSAgICBjYXNlIFNCQVJfTEVGVDoKCQkJWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdE9mZnNldCwgMCk7IG4rKzsKCQkJYnJlYWs7CgoJCSAgICBjYXNlIFNCQVJfUklHSFQ6CgkJCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0T2Zmc2V0LCAwKTsgbisrOwoJCQlicmVhazsKCgkJICAgIGNhc2UgU0JBUl9CT1RUT006CgkJCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbU9mZnNldCwgMCk7bisrOwoJCQlicmVhazsKCQl9CgkJWHRTZXRWYWx1ZXModGV4dEFyZWEsIGFyZ3MsIG4pOwoJICAgIH0KCSAgICBYdFVubWFuYWdlQ2hpbGQoc2ItPmlkKTsKCX0KICAgIH0KfQoKICAgIHZvaWQKZ3VpX21jaF9jcmVhdGVfc2Nyb2xsYmFyKHNiLCBvcmllbnQpCiAgICBzY3JvbGxiYXJfVCAqc2I7CiAgICBpbnQJCW9yaWVudDsJLyogU0JBUl9WRVJUIG9yIFNCQVJfSE9SSVogKi8KewogICAgQXJnCQlhcmdzWzE2XTsKICAgIGludAkJbjsKCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm1pbmltdW0sIDApOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5vcmllbnRhdGlvbiwKCSAgICAob3JpZW50ID09IFNCQVJfVkVSVCkgPyBYbVZFUlRJQ0FMIDogWG1IT1JJWk9OVEFMKTsgbisrOwoKICAgIHN3aXRjaCAoc2ItPnR5cGUpCiAgICB7CgljYXNlIFNCQVJfTEVGVDoKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX09QUE9TSVRFX0ZPUk0pOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgYnJlYWs7CgoJY2FzZSBTQkFSX1JJR0hUOgoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfT1BQT1NJVEVfRk9STSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgYnJlYWs7CgoJY2FzZSBTQkFSX0JPVFRPTToKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCSAgICBicmVhazsKICAgIH0KCiAgICBzYi0+aWQgPSBYdENyZWF0ZVdpZGdldCgic2Nyb2xsQmFyIiwKCSAgICB4bVNjcm9sbEJhcldpZGdldENsYXNzLCB0ZXh0QXJlYUZvcm0sIGFyZ3MsIG4pOwoKICAgIC8qIFJlbWVtYmVyIHRoZSBkZWZhdWx0IGNvbG9ycywgbmVlZGVkIGZvciAiOmhpIGNsZWFyIi4gKi8KICAgIGlmIChndWkuc2Nyb2xsX2RlZl9iZ19waXhlbCA9PSAoZ3VpY29sb3JfVCkwCgkgICAgJiYgZ3VpLnNjcm9sbF9kZWZfZmdfcGl4ZWwgPT0gKGd1aWNvbG9yX1QpMCkKCVh0VmFHZXRWYWx1ZXMoc2ItPmlkLAoJCVhtTmJhY2tncm91bmQsICZndWkuc2Nyb2xsX2RlZl9iZ19waXhlbCwKCQlYbU5mb3JlZ3JvdW5kLCAmZ3VpLnNjcm9sbF9kZWZfZmdfcGl4ZWwsCgkJTlVMTCk7CgogICAgaWYgKHNiLT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglndWlfbWNoX3NldF9zY3JvbGxiYXJfY29sb3JzKHNiKTsKCVh0QWRkQ2FsbGJhY2soc2ItPmlkLCBYbU52YWx1ZUNoYW5nZWRDYWxsYmFjaywKCQkgICAgICBzY3JvbGxfY2IsIChYdFBvaW50ZXIpc2ItPmlkZW50KTsKCVh0QWRkQ2FsbGJhY2soc2ItPmlkLCBYbU5kcmFnQ2FsbGJhY2ssCgkJICAgICAgc2Nyb2xsX2NiLCAoWHRQb2ludGVyKXNiLT5pZGVudCk7CglYdEFkZEV2ZW50SGFuZGxlcihzYi0+aWQsIEtleVByZXNzTWFzaywgRkFMU0UsIGd1aV94MTFfa2V5X2hpdF9jYiwKCSAgICAoWHRQb2ludGVyKTApOwogICAgfQp9CgojaWYgZGVmaW5lZChGRUFUX1dJTkRPV1MpIHx8IGRlZmluZWQoUFJPVE8pCiAgICB2b2lkCmd1aV9tY2hfZGVzdHJveV9zY3JvbGxiYXIoc2IpCiAgICBzY3JvbGxiYXJfVCAqc2I7CnsKICAgIGlmIChzYi0+aWQgIT0gKFdpZGdldCkwKQoJWHREZXN0cm95V2lkZ2V0KHNiLT5pZCk7Cn0KI2VuZGlmCgogICAgdm9pZApndWlfbWNoX3NldF9zY3JvbGxiYXJfY29sb3JzKHNiKQogICAgc2Nyb2xsYmFyX1QgKnNiOwp7CiAgICBpZiAoc2ItPmlkICE9IChXaWRnZXQpMCkKICAgIHsKCWlmIChndWkuc2Nyb2xsX2JnX3BpeGVsICE9IElOVkFMQ09MT1IpCgl7CiNpZiAoWG1WZXJzaW9uPj0xMDAyKQoJICAgIFhtQ2hhbmdlQ29sb3Ioc2ItPmlkLCBndWkuc2Nyb2xsX2JnX3BpeGVsKTsKI2Vsc2UKCSAgICBYdFZhU2V0VmFsdWVzKHNiLT5pZCwKCQkgICAgWG1OdHJvdWdoQ29sb3IsIGd1aS5zY3JvbGxfYmdfcGl4ZWwsCgkJICAgIE5VTEwpOwojZW5kaWYKCX0KCglpZiAoZ3VpLnNjcm9sbF9mZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJICAgIFh0VmFTZXRWYWx1ZXMoc2ItPmlkLAoJCSAgICBYbU5mb3JlZ3JvdW5kLCBndWkuc2Nyb2xsX2ZnX3BpeGVsLAojaWYgKFhtVmVyc2lvbjwxMDAyKQoJCSAgICBYbU5iYWNrZ3JvdW5kLCBndWkuc2Nyb2xsX2ZnX3BpeGVsLAojZW5kaWYKCQkgICAgTlVMTCk7CiAgICB9CgogICAgLyogVGhpcyBpcyBuZWVkZWQgZm9yIHRoZSByZWN0YW5nbGUgYmVsb3cgdGhlIHZlcnRpY2FsIHNjcm9sbGJhcnMuICovCiAgICBpZiAoc2IgPT0gJmd1aS5ib3R0b21fc2JhciAmJiB0ZXh0QXJlYUZvcm0gIT0gKFdpZGdldCkwKQoJZ3VpX21vdGlmX3Njcm9sbF9jb2xvcnModGV4dEFyZWFGb3JtKTsKfQoKLyoKICogTWlzY2VsbGFuZW91cyBzdHVmZjoKICovCgogICAgV2luZG93Cmd1aV94MTFfZ2V0X3dpZCgpCnsKICAgIHJldHVybihYdFdpbmRvdyh0ZXh0QXJlYSkpOwp9CgovKgogKiBMb29rIGZvciBhIHdpZGdldCBpbiB0aGUgd2lkZ2V0IHRyZWUgdywgd2l0aCBhIG1uZW1vbmljIG1hdGNoaW5nIGtleWNvZGUuCiAqIFdoZW4gb25lIGlzIGZvdW5kLCBzaW11bGF0ZSBhIGJ1dHRvbiBwcmVzcyBvbiB0aGF0IHdpZGdldCBhbmQgZ2l2ZSBpdCB0aGUKICoga2V5Ym9hcmQgZm9jdXMuICBJZiB0aGUgbW5lbW9uaWMgaXMgb24gYSBsYWJlbCwgbG9vayBpbiB0aGUgdXNlckRhdGEgZmllbGQKICogb2YgdGhlIGxhYmVsIHRvIHNlZSBpZiBpdCBwb2ludHMgdG8gYW5vdGhlciB3aWRnZXQsIGFuZCBnaXZlIHRoYXQgdGhlIGZvY3VzLgogKi8KICAgIHN0YXRpYyB2b2lkCmRvX21uZW1vbmljKFdpZGdldCB3LCB1bnNpZ25lZCBpbnQga2V5Y29kZSkKewogICAgV2lkZ2V0TGlzdAkgICAgY2hpbGRyZW47CiAgICBpbnQJCSAgICBudW1DaGlsZHJlbiwgaTsKICAgIEJvb2xlYW4JICAgIGlzTWVudTsKICAgIEtleVN5bQkgICAgbW5lbW9uaWMgPSAnXDAnOwogICAgY2hhcgkgICAgbW5lU3RyaW5nWzJdOwogICAgV2lkZ2V0CSAgICB1c2VyRGF0YTsKICAgIHVuc2lnbmVkIGNoYXIgICByb3dDb2xUeXBlOwoKICAgIGlmIChYdElzQ29tcG9zaXRlKHcpKQogICAgewoJaWYgKFh0Q2xhc3ModykgPT0geG1Sb3dDb2x1bW5XaWRnZXRDbGFzcykKCXsKCSAgICBYdFZhR2V0VmFsdWVzKHcsIFhtTnJvd0NvbHVtblR5cGUsICZyb3dDb2xUeXBlLCAwKTsKCSAgICBpc01lbnUgPSAocm93Q29sVHlwZSAhPSAodW5zaWduZWQgY2hhcilYbVdPUktfQVJFQSk7Cgl9CgllbHNlCgkgICAgaXNNZW51ID0gRmFsc2U7CglpZiAoIWlzTWVudSkKCXsKCSAgICBYdFZhR2V0VmFsdWVzKHcsIFhtTmNoaWxkcmVuLCAmY2hpbGRyZW4sIFhtTm51bUNoaWxkcmVuLAoJCQkgICZudW1DaGlsZHJlbiwgMCk7CgkgICAgZm9yIChpID0gMDsgaSA8IG51bUNoaWxkcmVuOyBpKyspCgkJZG9fbW5lbW9uaWMoY2hpbGRyZW5baV0sIGtleWNvZGUpOwoJfQogICAgfQogICAgZWxzZQogICAgewoJWHRWYUdldFZhbHVlcyh3LCBYbU5tbmVtb25pYywgJm1uZW1vbmljLCAwKTsKCWlmIChtbmVtb25pYyAhPSAnXDAnKQoJewoJICAgIG1uZVN0cmluZ1swXSA9IG1uZW1vbmljOwoJICAgIG1uZVN0cmluZ1sxXSA9ICdcMCc7CgkgICAgaWYgKFhLZXlzeW1Ub0tleWNvZGUoWHREaXNwbGF5KFh0UGFyZW50KHcpKSwKCQkJCSAgICAgICBYU3RyaW5nVG9LZXlzeW0obW5lU3RyaW5nKSkgPT0ga2V5Y29kZSkKCSAgICB7CgkJaWYgKFh0Q2xhc3ModykgPT0geG1MYWJlbFdpZGdldENsYXNzCgkJCXx8IFh0Q2xhc3ModykgPT0geG1MYWJlbEdhZGdldENsYXNzKQoJCXsKCQkgICAgWHRWYUdldFZhbHVlcyh3LCBYbU51c2VyRGF0YSwgJnVzZXJEYXRhLCAwKTsKCQkgICAgaWYgKHVzZXJEYXRhICE9IE5VTEwgJiYgWHRJc1dpZGdldCh1c2VyRGF0YSkpCgkJCVhtUHJvY2Vzc1RyYXZlcnNhbCh1c2VyRGF0YSwgWG1UUkFWRVJTRV9DVVJSRU5UKTsKCQl9CgkJZWxzZQoJCXsKCQkgICAgWEtleVByZXNzZWRFdmVudCBrZXlFdmVudDsKCgkJICAgIFhtUHJvY2Vzc1RyYXZlcnNhbCh3LCBYbVRSQVZFUlNFX0NVUlJFTlQpOwoKCQkgICAgbWVtc2V0KChjaGFyICopICZrZXlFdmVudCwgMCwgc2l6ZW9mKFhLZXlQcmVzc2VkRXZlbnQpKTsKCQkgICAga2V5RXZlbnQudHlwZSA9IEtleVByZXNzOwoJCSAgICBrZXlFdmVudC5zZXJpYWwgPSAxOwoJCSAgICBrZXlFdmVudC5zZW5kX2V2ZW50ID0gVHJ1ZTsKCQkgICAga2V5RXZlbnQuZGlzcGxheSA9IFh0RGlzcGxheSh3KTsKCQkgICAga2V5RXZlbnQud2luZG93ID0gWHRXaW5kb3codyk7CgkJICAgIFh0Q2FsbEFjdGlvblByb2ModywgIkFjdGl2YXRlIiwgKFhFdmVudCAqKSAmIGtleUV2ZW50LAoJCQkJCQkJCSAgICAgTlVMTCwgMCk7CgkJfQoJICAgIH0KCX0KICAgIH0KfQoKLyoKICogQ2FsbGJhY2sgcm91dGluZSBmb3IgZGlhbG9nIG1uZW1vbmljIHByb2Nlc3NpbmcuCiAqLwovKkFSR1NVU0VEKi8KICAgIHN0YXRpYyB2b2lkCm1uZW1vbmljX2V2ZW50KFdpZGdldCB3LCBYdFBvaW50ZXIgY2FsbF9kYXRhLCBYS2V5RXZlbnQgKmV2ZW50KQp7CiAgICBkb19tbmVtb25pYyh3LCBldmVudC0+a2V5Y29kZSk7Cn0KCgovKgogKiBTZWFyY2ggdGhlIHdpZGdldCB0cmVlIHVuZGVyIHcgZm9yIHdpZGdldHMgd2l0aCBtbmVtb25pY3MuICBXaGVuIGZvdW5kLCBhZGQKICogYSBwYXNzaXZlIGdyYWIgdG8gdGhlIGRpYWxvZyB3aWRnZXQgZm9yIHRoZSBtbmVtb25pYyBjaGFyYWN0ZXIsIHRodXMKICogZGlyZWN0aW5nIG1uZW1vbmljIGV2ZW50cyB0byB0aGUgZGlhbG9nIHdpZGdldC4KICovCiAgICBzdGF0aWMgdm9pZAphZGRfbW5lbW9uaWNfZ3JhYnMoV2lkZ2V0IGRpYWxvZywgV2lkZ2V0IHcpCnsKICAgIGNoYXIJICAgIG1uZVN0cmluZ1syXTsKICAgIFdpZGdldExpc3QJICAgIGNoaWxkcmVuOwogICAgaW50CQkgICAgbnVtQ2hpbGRyZW4sIGk7CiAgICBCb29sZWFuCSAgICBpc01lbnU7CiAgICBLZXlTeW0JICAgIG1uZW1vbmljID0gJ1wwJzsKICAgIHVuc2lnbmVkIGNoYXIgICByb3dDb2xUeXBlOwoKICAgIGlmIChYdElzQ29tcG9zaXRlKHcpKQogICAgewoJaWYgKFh0Q2xhc3ModykgPT0geG1Sb3dDb2x1bW5XaWRnZXRDbGFzcykKCXsKCSAgICBYdFZhR2V0VmFsdWVzKHcsIFhtTnJvd0NvbHVtblR5cGUsICZyb3dDb2xUeXBlLCAwKTsKCSAgICBpc01lbnUgPSAocm93Q29sVHlwZSAhPSAodW5zaWduZWQgY2hhcilYbVdPUktfQVJFQSk7Cgl9CgllbHNlCgkgICAgaXNNZW51ID0gRmFsc2U7CglpZiAoIWlzTWVudSkKCXsKCSAgICBYdFZhR2V0VmFsdWVzKHcsIFhtTmNoaWxkcmVuLCAmY2hpbGRyZW4sIFhtTm51bUNoaWxkcmVuLAoJCQkJCQkJICAgICAmbnVtQ2hpbGRyZW4sIDApOwoJICAgIGZvciAoaSA9IDA7IGkgPCBudW1DaGlsZHJlbjsgaSsrKQoJCWFkZF9tbmVtb25pY19ncmFicyhkaWFsb2csIGNoaWxkcmVuW2ldKTsKCX0KICAgIH0KICAgIGVsc2UKICAgIHsKCVh0VmFHZXRWYWx1ZXModywgWG1ObW5lbW9uaWMsICZtbmVtb25pYywgMCk7CglpZiAobW5lbW9uaWMgIT0gJ1wwJykKCXsKCSAgICBtbmVTdHJpbmdbMF0gPSBtbmVtb25pYzsKCSAgICBtbmVTdHJpbmdbMV0gPSAnXDAnOwoJICAgIFh0R3JhYktleShkaWFsb2csIFhLZXlzeW1Ub0tleWNvZGUoWHREaXNwbGF5KGRpYWxvZyksCgkJCQkJCSAgWFN0cmluZ1RvS2V5c3ltKG1uZVN0cmluZykpLAoJCSAgICBNb2QxTWFzaywgVHJ1ZSwgR3JhYk1vZGVBc3luYywgR3JhYk1vZGVBc3luYyk7Cgl9CiAgICB9Cn0KCi8qCiAqIEFkZCBhIGhhbmRsZXIgZm9yIG1uZW1vbmljcyBpbiBhIGRpYWxvZy4gIE1vdGlmIGl0c2VsZiBvbmx5IGhhbmRsZXMKICogbW5lbW9uaWNzIGluIG1lbnVzLiBNbmVtb25pY3MgYWRkZWQgb3IgY2hhbmdlZCBhZnRlciB0aGlzIGNhbGwgd2lsbCBiZQogKiBpZ25vcmVkLgogKgogKiBUbyBhZGQgYSBtbmVtb25pYyB0byBhIHRleHQgZmllbGQgb3IgbGlzdCwgc2V0IHRoZSBYbU5tbmVtb25pYyByZXNvdXJjZSBvbgogKiB0aGUgYXBwcm9wcmlhdGUgbGFiZWwgYW5kIHNldCB0aGUgWG1OdXNlckRhdGEgcmVzb3VyY2Ugb2YgdGhlIGxhYmVsIHRvIHRoZQogKiB3aWRnZXQgdG8gZ2V0IHRoZSBmb2N1cyB3aGVuIHRoZSBtbmVtb25pYyBpcyB0eXBlZC4KICovCiAgICBzdGF0aWMgdm9pZAphY3RpdmF0ZV9kaWFsb2dfbW5lbW9uaWNzKFdpZGdldCBkaWFsb2cpCnsKICAgIGlmICghZGlhbG9nKQoJcmV0dXJuOwoKICAgIFh0QWRkRXZlbnRIYW5kbGVyKGRpYWxvZywgS2V5UHJlc3NNYXNrLCBGYWxzZSwKCQkJICAgKFh0RXZlbnRIYW5kbGVyKSBtbmVtb25pY19ldmVudCwgKFh0UG9pbnRlcikgTlVMTCk7CiAgICBhZGRfbW5lbW9uaWNfZ3JhYnMoZGlhbG9nLCBkaWFsb2cpOwp9CgovKgogKiBSZW1vdmVzIHRoZSBldmVudCBoYW5kbGVyIGFuZCBrZXktZ3JhYnMgZm9yIGRpYWxvZyBtbmVtb25pYyBoYW5kbGluZy4KICovCiAgICBzdGF0aWMgdm9pZApzdXBwcmVzc19kaWFsb2dfbW5lbW9uaWNzKFdpZGdldCBkaWFsb2cpCnsKICAgIGlmICghZGlhbG9nKQoJcmV0dXJuOwoKICAgIFh0VW5ncmFiS2V5KGRpYWxvZywgQW55S2V5LCBNb2QxTWFzayk7CiAgICBYdFJlbW92ZUV2ZW50SGFuZGxlcihkaWFsb2csIEtleVByZXNzTWFzaywgRmFsc2UsCgkJCSAgIChYdEV2ZW50SGFuZGxlcikgbW5lbW9uaWNfZXZlbnQsIChYdFBvaW50ZXIpIE5VTEwpOwp9CgojaWYgZGVmaW5lZChGRUFUX0JST1dTRSkgfHwgZGVmaW5lZChGRUFUX0dVSV9ESUFMT0cpCnN0YXRpYyB2b2lkIHNldF9mb250bGlzdCBfX0FSR1MoKFdpZGdldCB3ZykpOwoKLyoKICogVXNlIHRoZSAnZ3VpZm9udCcgb3IgJ2d1aWZvbnRzZXQnIGFzIGEgZm9udGxpc3QgZm9yIGEgZGlhbG9nIHdpZGdldC4KICovCiAgICBzdGF0aWMgdm9pZApzZXRfZm9udGxpc3QoaWQpCiAgICBXaWRnZXQgaWQ7CnsKICAgIFhtRm9udExpc3QgZmw7CgojaWZkZWYgRk9OVFNFVF9BTFdBWVMKICAgIGlmIChndWkuZm9udHNldCAhPSBOT0ZPTlRTRVQpCiAgICB7CglmbCA9IGd1aV9tb3RpZl9mb250c2V0MmZvbnRsaXN0KChYRm9udFNldCAqKSZndWkuZm9udHNldCk7CglpZiAoZmwgIT0gTlVMTCkKCXsKCSAgICBpZiAoWHRJc01hbmFnZWQoaWQpKQoJICAgIHsKCQlYdFVubWFuYWdlQ2hpbGQoaWQpOwoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkJLyogV2Ugc2hvdWxkIGZvcmNlIHRoZSB3aWRnZXQgdG8gcmVjYWxjdWxhdGUgaXQncwoJCSAqIGdlb21ldHJ5IG5vdy4gKi8KCQlYdE1hbmFnZUNoaWxkKGlkKTsKCSAgICB9CgkgICAgZWxzZQoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkgICAgWG1Gb250TGlzdEZyZWUoZmwpOwoJfQogICAgfQojZWxzZQogICAgaWYgKGd1aS5ub3JtX2ZvbnQgIT0gTk9GT05UKQogICAgewoJZmwgPSBndWlfbW90aWZfY3JlYXRlX2ZvbnRsaXN0KChYRm9udFN0cnVjdCAqKWd1aS5ub3JtX2ZvbnQpOwoJaWYgKGZsICE9IE5VTEwpCgl7CgkgICAgaWYgKFh0SXNNYW5hZ2VkKGlkKSkKCSAgICB7CgkJWHRVbm1hbmFnZUNoaWxkKGlkKTsKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJCS8qIFdlIHNob3VsZCBmb3JjZSB0aGUgd2lkZ2V0IHRvIHJlY2FsY3VsYXRlIGl0J3MKCQkgKiBnZW9tZXRyeSBub3cuICovCgkJWHRNYW5hZ2VDaGlsZChpZCk7CgkgICAgfQoJICAgIGVsc2UKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJICAgIFhtRm9udExpc3RGcmVlKGZsKTsKCX0KICAgIH0KI2VuZGlmCn0KI2VuZGlmCgojaWYgZGVmaW5lZChGRUFUX0JST1dTRSkgfHwgZGVmaW5lZChQUk9UTykKCi8qCiAqIGZpbGUgc2VsZWN0b3IgcmVsYXRlZCBzdHVmZgogKi8KCiNpbmNsdWRlIDxYbS9GaWxlU0IuaD4KI2luY2x1ZGUgPFhtL1htU3RyRGVmcy5oPgoKdHlwZWRlZiBzdHJ1Y3QgZGlhbG9nX2NhbGxiYWNrX2FyZwp7CiAgICBjaGFyICogIGFyZ3M7ICAgLyogbm90IHVzZWQgcmlnaHQgbm93ICovCiAgICBpbnQJICAgIGlkOwp9IGRjYmFyZ19UOwoKc3RhdGljIFdpZGdldCBkaWFsb2dfd2d0OwpzdGF0aWMgY2hhciAqYnJvd3NlX2ZuYW1lID0gTlVMTDsKc3RhdGljIFhtU3RyaW5nQ2hhclNldCBjaGFyc2V0ID0gKFhtU3RyaW5nQ2hhclNldCkgWG1TVFJJTkdfREVGQVVMVF9DSEFSU0VUOwoJCQkJLyogdXNlZCB0byBzZXQgdXAgWG1TdHJpbmdzICovCgpzdGF0aWMgdm9pZCBEaWFsb2dDYW5jZWxDQiBfX0FSR1MoKFdpZGdldCwgWHRQb2ludGVyLCBYdFBvaW50ZXIpKTsKc3RhdGljIHZvaWQgRGlhbG9nQWNjZXB0Q0IgX19BUkdTKChXaWRnZXQsIFh0UG9pbnRlciwgWHRQb2ludGVyKSk7CgovKgogKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gdHJhbnNsYXRlIHRoZSBwcmVkZWZpbmVkIGxhYmVsIHRleHQgb2YgdGhlCiAqIHByZWNvbXBvc2VkIGRpYWxvZ3MuIFdlIGRvIHRoaXMgZXhwbGljaXRseSB0byBhbGxvdzoKICoKICogLSB1c2FnZSBvZiBnZXR0ZXh0IGZvciB0cmFuc2xhdGlvbiwgYXMgaW4gYWxsIHRoZSBvdGhlciBwbGFjZXMuCiAqCiAqIC0gZXF1YWxpemUgdGhlIG1lc3NhZ2VzIGJldHdlZW4gZGlmZmVyZW50IEdVSSBpbXBsZW1lbnRhdGlvbnMgYXMgZmFyIGFzCiAqIHBvc3NpYmxlLgogKi8Kc3RhdGljIHZvaWQgc2V0X3ByZWRlZmluZWRfbGFiZWwgX19BUkdTKChXaWRnZXQgcGFyZW50LCBTdHJpbmcgbmFtZSwgY2hhciAqbmV3X2xhYmVsKSk7CgpzdGF0aWMgdm9pZApzZXRfcHJlZGVmaW5lZF9sYWJlbChwYXJlbnQsIG5hbWUsIG5ld19sYWJlbCkKICAgIFdpZGdldCAgcGFyZW50OwogICAgU3RyaW5nICBuYW1lOwogICAgY2hhciAgICAqbmV3X2xhYmVsOwp7CiAgICBYbVN0cmluZwlzdHI7CiAgICBXaWRnZXQJdzsKICAgIGNoYXJfdQkqcCwgKm5leHQ7CiAgICBLZXlTeW0JbW5lbW9uaWMgPSBOVUw7CgogICAgdyA9IFh0TmFtZVRvV2lkZ2V0KHBhcmVudCwgbmFtZSk7CgogICAgaWYgKCF3KQoJcmV0dXJuOwoKICAgIHAgPSB2aW1fc3Ryc2F2ZSgoY2hhcl91ICopbmV3X2xhYmVsKTsKICAgIGlmIChwID09IE5VTEwpCglyZXR1cm47CiAgICBmb3IgKG5leHQgPSBwOyAqbmV4dDsgKytuZXh0KQogICAgewoJaWYgKCpuZXh0ID09IERMR19IT1RLRVlfQ0hBUikKCXsKCSAgICBpbnQgbGVuID0gU1RSTEVOKG5leHQpOwoKCSAgICBpZiAobGVuID4gMCkKCSAgICB7CgkJbWNoX21lbW1vdmUobmV4dCwgbmV4dCArIDEsIGxlbik7CgkJbW5lbW9uaWMgPSBuZXh0WzBdOwoJICAgIH0KCX0KICAgIH0KCiAgICBzdHIgPSBYbVN0cmluZ0NyZWF0ZSgoY2hhciAqKXAsIFNUUklOR19UQUcpOwogICAgdmltX2ZyZWUocCk7CgogICAgaWYgKHN0ciAhPSBOVUxMKQogICAgewoJWHRWYVNldFZhbHVlcyh3LAoJCVhtTmxhYmVsU3RyaW5nLCBzdHIsCgkJWG1ObW5lbW9uaWMsIG1uZW1vbmljLAoJCU5VTEwpOwoJWG1TdHJpbmdGcmVlKHN0cik7CiAgICB9CiAgICBndWlfbW90aWZfbWVudV9mb250bGlzdCh3KTsKfQoKc3RhdGljIHZvaWQKc2V0X3ByZWRlZmluZWRfZm9udGxpc3QocGFyZW50LCBuYW1lKQogICAgV2lkZ2V0IHBhcmVudDsKICAgIFN0cmluZyBuYW1lOwp7CiAgICBXaWRnZXQgdzsKICAgIHcgPSBYdE5hbWVUb1dpZGdldChwYXJlbnQsIG5hbWUpOwoKICAgIGlmICghdykKCXJldHVybjsKCiAgICBzZXRfZm9udGxpc3Qodyk7Cn0KCi8qCiAqIFB1dCB1cCBhIGZpbGUgcmVxdWVzdGVyLgogKiBSZXR1cm5zIHRoZSBzZWxlY3RlZCBuYW1lIGluIGFsbG9jYXRlZCBtZW1vcnksIG9yIE5VTEwgZm9yIENhbmNlbC4KICovCi8qIEFSR1NVU0VEICovCiAgICBjaGFyX3UgKgpndWlfbWNoX2Jyb3dzZShzYXZpbmcsIHRpdGxlLCBkZmx0LCBleHQsIGluaXRkaXIsIGZpbHRlcikKICAgIGludAkJc2F2aW5nOwkJLyogc2VsZWN0IGZpbGUgdG8gd3JpdGUgKi8KICAgIGNoYXJfdQkqdGl0bGU7CQkvKiB0aXRsZSBmb3IgdGhlIHdpbmRvdyAqLwogICAgY2hhcl91CSpkZmx0OwkJLyogZGVmYXVsdCBuYW1lICovCiAgICBjaGFyX3UJKmV4dDsJCS8qIG5vdCB1c2VkIChleHRlbnNpb24gYWRkZWQpICovCiAgICBjaGFyX3UJKmluaXRkaXI7CS8qIGluaXRpYWwgZGlyZWN0b3J5LCBOVUxMIGZvciBjdXJyZW50IGRpciAqLwogICAgY2hhcl91CSpmaWx0ZXI7CS8qIGZpbGUgbmFtZSBmaWx0ZXIgKi8KewogICAgY2hhcl91CWRpcmJ1ZltNQVhQQVRITF07CiAgICBjaGFyX3UJZGZsdGJ1ZltNQVhQQVRITF07CiAgICBjaGFyX3UJKnBhdHRlcm47CiAgICBjaGFyX3UJKnRvZnJlZSA9IE5VTEw7CgogICAgLyogVGhlcmUgYSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHJlc291cmNlIG5hbWUgYW5kIHZhbHVlLCBUaGVyZWZvcmUsIHdlCiAgICAgKiBhdm9pZCB0byAoYWItKXVzZSB0aGUgKG1heWJlIGludGVybmF0aW9uYWxpemVkISkgZGlhbG9nIHRpdGxlIGFzIGEKICAgICAqIGRpYWxvZyBuYW1lLgogICAgICovCgogICAgZGlhbG9nX3dndCA9IFhtQ3JlYXRlRmlsZVNlbGVjdGlvbkRpYWxvZyh2aW1TaGVsbCwgImJyb3dzZURpYWxvZyIsIE5VTEwsIDApOwoKICAgIGlmIChpbml0ZGlyID09IE5VTEwgfHwgKmluaXRkaXIgPT0gTlVMKQogICAgewoJbWNoX2Rpcm5hbWUoZGlyYnVmLCBNQVhQQVRITCk7Cglpbml0ZGlyID0gZGlyYnVmOwogICAgfQoKICAgIGlmIChkZmx0ID09IE5VTEwpCglkZmx0ID0gKGNoYXJfdSAqKSIiOwogICAgZWxzZSBpZiAoU1RSTEVOKGluaXRkaXIpICsgU1RSTEVOKGRmbHQpICsgMiA8IE1BWFBBVEhMKQogICAgewoJLyogVGhlIGRlZmF1bHQgc2VsZWN0aW9uIHNob3VsZCBiZSB0aGUgZnVsbCBwYXRoLCAiZGZsdCIgaXMgb25seSB0aGUKCSAqIGZpbGUgbmFtZS4gKi8KCVNUUkNQWShkZmx0YnVmLCBpbml0ZGlyKTsKCWFkZF9wYXRoc2VwKGRmbHRidWYpOwoJU1RSQ0FUKGRmbHRidWYsIGRmbHQpOwoJZGZsdCA9IGRmbHRidWY7CiAgICB9CgogICAgLyogQ2FuIG9ubHkgdXNlIG9uZSBwYXR0ZXJuIGZvciBhIGZpbGUgbmFtZS4gIEdldCB0aGUgZmlyc3QgcGF0dGVybiBvdXQgb2YKICAgICAqIHRoZSBmaWx0ZXIuICBBbiBlbXB0eSBwYXR0ZXJuIG1lYW5zIGV2ZXJ5dGhpbmcgbWF0Y2hlcy4gKi8KICAgIGlmIChmaWx0ZXIgPT0gTlVMTCkKCXBhdHRlcm4gPSAoY2hhcl91ICopIiI7CiAgICBlbHNlCiAgICB7CgljaGFyX3UJKnMsICpwOwoKCXMgPSBmaWx0ZXI7Cglmb3IgKHAgPSBmaWx0ZXI7ICpwICE9IE5VTDsgKytwKQoJewoJICAgIGlmICgqcCA9PSAnXHQnKQkvKiBlbmQgb2YgZGVzY3JpcHRpb24sIHN0YXJ0IG9mIHBhdHRlcm4gKi8KCQlzID0gcCArIDE7CgkgICAgaWYgKCpwID09ICc7JyB8fCAqcCA9PSAnXG4nKQkvKiBlbmQgb2YgKGZpcnN0KSBwYXR0ZXJuICovCgkJYnJlYWs7Cgl9CglwYXR0ZXJuID0gdmltX3N0cm5zYXZlKHMsIHAgLSBzKTsKCXRvZnJlZSA9IHBhdHRlcm47CglpZiAocGF0dGVybiA9PSBOVUxMKQoJICAgIHBhdHRlcm4gPSAoY2hhcl91ICopIiI7CiAgICB9CgogICAgWHRWYVNldFZhbHVlcyhkaWFsb2dfd2d0LAoJWHRWYVR5cGVkQXJnLAoJICAgIFhtTmRpcmVjdG9yeSwgWG1SU3RyaW5nLCAoY2hhciAqKWluaXRkaXIsIFNUUkxFTihpbml0ZGlyKSArIDEsCglYdFZhVHlwZWRBcmcsCgkgICAgWG1OZGlyU3BlYywJWG1SU3RyaW5nLCAoY2hhciAqKWRmbHQsIFNUUkxFTihkZmx0KSArIDEsCglYdFZhVHlwZWRBcmcsCgkgICAgWG1OcGF0dGVybiwJWG1SU3RyaW5nLCAoY2hhciAqKXBhdHRlcm4sIFNUUkxFTihwYXR0ZXJuKSArIDEsCglYdFZhVHlwZWRBcmcsCgkgICAgWG1OZGlhbG9nVGl0bGUsIFhtUlN0cmluZywgKGNoYXIgKil0aXRsZSwgU1RSTEVOKHRpdGxlKSArIDEsCglOVUxMKTsKCiAgICBzZXRfcHJlZGVmaW5lZF9sYWJlbChkaWFsb2dfd2d0LCAiQXBwbHkiLCBfKCImRmlsdGVyIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkNhbmNlbCIsIF8oIiZDYW5jZWwiKSk7CiAgICBzZXRfcHJlZGVmaW5lZF9sYWJlbChkaWFsb2dfd2d0LCAiRGlyIiwgXygiRGlyZWN0b3JpZXMiKSk7CiAgICBzZXRfcHJlZGVmaW5lZF9sYWJlbChkaWFsb2dfd2d0LCAiRmlsdGVyTGFiZWwiLCBfKCJGaWx0ZXIiKSk7CiAgICBzZXRfcHJlZGVmaW5lZF9sYWJlbChkaWFsb2dfd2d0LCAiSGVscCIsIF8oIiZIZWxwIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkl0ZW1zIiwgXygiRmlsZXMiKSk7CiAgICBzZXRfcHJlZGVmaW5lZF9sYWJlbChkaWFsb2dfd2d0LCAiT0siLCBfKCImT0siKSk7CiAgICBzZXRfcHJlZGVmaW5lZF9sYWJlbChkaWFsb2dfd2d0LCAiU2VsZWN0aW9uIiwgXygiU2VsZWN0aW9uIikpOwoKICAgIC8qIFRoaXMgaXMgdG8gc2F2ZSB1cyBmcm9tIHNpbGx5IGV4dGVybmFsIHNldHRpbmdzIHVzaW5nIG5vdCBmaXhlZCB3aXRoCiAgICAgKiBmb250cyBmb3IgZmlsZSBzZWxlY3Rpb24uCiAgICAgKi8KICAgIHNldF9wcmVkZWZpbmVkX2ZvbnRsaXN0KGRpYWxvZ193Z3QsICJEaXJMaXN0U1cuRGlyTGlzdCIpOwogICAgc2V0X3ByZWRlZmluZWRfZm9udGxpc3QoZGlhbG9nX3dndCwgIkl0ZW1zTGlzdFNXLkl0ZW1zTGlzdCIpOwoKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyhkaWFsb2dfd2d0KTsKICAgIGlmIChndWkuc2Nyb2xsX2JnX3BpeGVsICE9IElOVkFMQ09MT1IpCglYdFZhU2V0VmFsdWVzKGRpYWxvZ193Z3QsIFhtTnRyb3VnaENvbG9yLCBndWkuc2Nyb2xsX2JnX3BpeGVsLCBOVUxMKTsKCiAgICBYdEFkZENhbGxiYWNrKGRpYWxvZ193Z3QsIFhtTm9rQ2FsbGJhY2ssIERpYWxvZ0FjY2VwdENCLCAoWHRQb2ludGVyKTApOwogICAgWHRBZGRDYWxsYmFjayhkaWFsb2dfd2d0LCBYbU5jYW5jZWxDYWxsYmFjaywgRGlhbG9nQ2FuY2VsQ0IsIChYdFBvaW50ZXIpMCk7CiAgICAvKiBXZSBoYXZlIG5vIGhlbHAgaW4gdGhpcyB3aW5kb3csIHNvIGhpZGUgaGVscCBidXR0b24gKi8KICAgIFh0VW5tYW5hZ2VDaGlsZChYbUZpbGVTZWxlY3Rpb25Cb3hHZXRDaGlsZChkaWFsb2dfd2d0LAoJCQkJCSh1bnNpZ25lZCBjaGFyKVhtRElBTE9HX0hFTFBfQlVUVE9OKSk7CgogICAgbWFuYWdlX2NlbnRlcmVkKGRpYWxvZ193Z3QpOwogICAgYWN0aXZhdGVfZGlhbG9nX21uZW1vbmljcyhkaWFsb2dfd2d0KTsKCiAgICAvKiBzaXQgaW4gYSBsb29wIHVudGlsIHRoZSBkaWFsb2cgYm94IGhhcyBnb25lIGF3YXkgKi8KICAgIGRvCiAgICB7CglYdEFwcFByb2Nlc3NFdmVudChYdFdpZGdldFRvQXBwbGljYXRpb25Db250ZXh0KGRpYWxvZ193Z3QpLAoJICAgIChYdElucHV0TWFzaylYdElNQWxsKTsKICAgIH0gd2hpbGUgKFh0SXNNYW5hZ2VkKGRpYWxvZ193Z3QpKTsKCiAgICBzdXBwcmVzc19kaWFsb2dfbW5lbW9uaWNzKGRpYWxvZ193Z3QpOwogICAgWHREZXN0cm95V2lkZ2V0KGRpYWxvZ193Z3QpOwogICAgdmltX2ZyZWUodG9mcmVlKTsKCiAgICBpZiAoYnJvd3NlX2ZuYW1lID09IE5VTEwpCglyZXR1cm4gTlVMTDsKICAgIHJldHVybiB2aW1fc3Ryc2F2ZSgoY2hhcl91ICopYnJvd3NlX2ZuYW1lKTsKfQoKLyoKICogVGhlIGNvZGUgYmVsb3cgd2FzIG9yaWdpbmFsbHkgdGFrZW4gZnJvbQogKgkvdXNyL2V4YW1wbGVzL21vdGlmL3htc2FtcGxlcnMveG1lZGl0b3IuYwogKiBvbiBEaWdpdGFsIFVuaXggNC4wZCwgYnV0IGhlYXZpbHkgbW9kaWZpZWQuCiAqLwoKLyoKICogUHJvY2VzcyBjYWxsYmFjayBmcm9tIERpYWxvZyBjYW5jZWwgYWN0aW9ucy4KICovCi8qIEFSR1NVU0VEICovCiAgICBzdGF0aWMgdm9pZApEaWFsb2dDYW5jZWxDQih3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXc7CQkvKiAgd2lkZ2V0IGlkCQkqLwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwkvKiAgZGF0YSBmcm9tIGFwcGxpY2F0aW9uICAgKi8KICAgIFh0UG9pbnRlcgljYWxsX2RhdGE7CS8qICBkYXRhIGZyb20gd2lkZ2V0IGNsYXNzICAqLwp7CiAgICBpZiAoYnJvd3NlX2ZuYW1lICE9IE5VTEwpCiAgICB7CglYdEZyZWUoYnJvd3NlX2ZuYW1lKTsKCWJyb3dzZV9mbmFtZSA9IE5VTEw7CiAgICB9CiAgICBYdFVubWFuYWdlQ2hpbGQoZGlhbG9nX3dndCk7Cn0KCi8qCiAqIFByb2Nlc3MgY2FsbGJhY2sgZnJvbSBEaWFsb2cgYWN0aW9ucy4KICovCi8qIEFSR1NVU0VEICovCiAgICBzdGF0aWMgdm9pZApEaWFsb2dBY2NlcHRDQih3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXc7CQkvKiAgd2lkZ2V0IGlkCQkqLwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwkvKiAgZGF0YSBmcm9tIGFwcGxpY2F0aW9uICAgKi8KICAgIFh0UG9pbnRlcgljYWxsX2RhdGE7CS8qICBkYXRhIGZyb20gd2lkZ2V0IGNsYXNzICAqLwp7CiAgICBYbUZpbGVTZWxlY3Rpb25Cb3hDYWxsYmFja1N0cnVjdCAqZmNiOwoKICAgIGlmIChicm93c2VfZm5hbWUgIT0gTlVMTCkKICAgIHsKCVh0RnJlZShicm93c2VfZm5hbWUpOwoJYnJvd3NlX2ZuYW1lID0gTlVMTDsKICAgIH0KICAgIGZjYiA9IChYbUZpbGVTZWxlY3Rpb25Cb3hDYWxsYmFja1N0cnVjdCAqKWNhbGxfZGF0YTsKCiAgICAvKiBnZXQgdGhlIGZpbGVuYW1lIGZyb20gdGhlIGZpbGUgc2VsZWN0aW9uIGJveCAqLwogICAgWG1TdHJpbmdHZXRMdG9SKGZjYi0+dmFsdWUsIGNoYXJzZXQsICZicm93c2VfZm5hbWUpOwoKICAgIC8qIHBvcGRvd24gdGhlIGZpbGUgc2VsZWN0aW9uIGJveCAqLwogICAgWHRVbm1hbmFnZUNoaWxkKGRpYWxvZ193Z3QpOwp9CgojZW5kaWYgLyogRkVBVF9CUk9XU0UgKi8KCiNpZiBkZWZpbmVkKEZFQVRfR1VJX0RJQUxPRykgfHwgZGVmaW5lZChQUk9UTykKCnN0YXRpYyBpbnQJZGlhbG9nU3RhdHVzOwoKc3RhdGljIHZvaWQga2V5aGl0X2NhbGxiYWNrIF9fQVJHUygoV2lkZ2V0IHcsIFh0UG9pbnRlciBjbGllbnRfZGF0YSwgWEV2ZW50ICpldmVudCwgQm9vbGVhbiAqY29udCkpOwpzdGF0aWMgdm9pZCBidXRwcm9jIF9fQVJHUygoV2lkZ2V0IHcsIFh0UG9pbnRlciBjbGllbnRfZGF0YSwgWHRQb2ludGVyIGNhbGxfZGF0YSkpOwoKLyoKICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIHRoZSB0ZXh0ZmllbGQuICBXaGVuIENSIGlzIGhpdCB0aGlzIHdvcmtzIGxpa2UKICogaGl0dGluZyB0aGUgIk9LIiBidXR0b24sIEVTQyBsaWtlICJDYW5jZWwiLgogKi8KLyogQVJHU1VTRUQgKi8KICAgIHN0YXRpYyB2b2lkCmtleWhpdF9jYWxsYmFjayh3LCBjbGllbnRfZGF0YSwgZXZlbnQsIGNvbnQpCiAgICBXaWRnZXQJCXc7CiAgICBYdFBvaW50ZXIJCWNsaWVudF9kYXRhOwogICAgWEV2ZW50CQkqZXZlbnQ7CiAgICBCb29sZWFuCQkqY29udDsKewogICAgY2hhcglidWZbMl07CiAgICBLZXlTeW0Ja2V5X3N5bTsKCiAgICBpZiAoWExvb2t1cFN0cmluZygmKGV2ZW50LT54a2V5KSwgYnVmLCAyLCAma2V5X3N5bSwgTlVMTCkgPT0gMSkKICAgIHsKCWlmICgqYnVmID09IENBUikKCSAgICBkaWFsb2dTdGF0dXMgPSAxOwoJZWxzZSBpZiAoKmJ1ZiA9PSBFU0MpCgkgICAgZGlhbG9nU3RhdHVzID0gMjsKICAgIH0KICAgIGlmICgoa2V5X3N5bSA9PSBYS19MZWZ0IHx8IGtleV9zeW0gPT0gWEtfUmlnaHQpCgkgICAgJiYgIShldmVudC0+eGtleS5zdGF0ZSAmIFNoaWZ0TWFzaykpCglYbVRleHRGaWVsZENsZWFyU2VsZWN0aW9uKHcsIFh0TGFzdFRpbWVzdGFtcFByb2Nlc3NlZChndWkuZHB5KSk7Cn0KCi8qIEFSR1NVU0VEICovCiAgICBzdGF0aWMgdm9pZApidXRwcm9jKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdzsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsKICAgIFh0UG9pbnRlcgljYWxsX2RhdGE7CnsKICAgIGRpYWxvZ1N0YXR1cyA9IChpbnQpKGxvbmcpY2xpZW50X2RhdGEgKyAxOwp9CgojaWZkZWYgSEFWRV9YUE0KCnN0YXRpYyBXaWRnZXQgY3JlYXRlX3BpeG1hcF9sYWJlbChXaWRnZXQgcGFyZW50LCBTdHJpbmcgbmFtZSwgY2hhciAqKmRhdGEsIEFyZ0xpc3QgYXJncywgQ2FyZGluYWwgYXJnKTsKCiAgICBzdGF0aWMgV2lkZ2V0CmNyZWF0ZV9waXhtYXBfbGFiZWwocGFyZW50LCBuYW1lLCBkYXRhLCBhcmdzLCBhcmcpCiAgICBXaWRnZXQJcGFyZW50OwogICAgU3RyaW5nCW5hbWU7CiAgICBjaGFyCSoqZGF0YTsKICAgIEFyZ0xpc3QJYXJnczsKICAgIENhcmRpbmFsCWFyZzsKewogICAgV2lkZ2V0CQlsYWJlbDsKICAgIERpc3BsYXkJCSpkc3A7CiAgICBTY3JlZW4JCSpzY3I7CiAgICBpbnQJCQlkZXB0aDsKICAgIFBpeG1hcAkJcGl4bWFwID0gMDsKICAgIFhwbUF0dHJpYnV0ZXMJYXR0cjsKICAgIEJvb2xlYW4JCXJzOwogICAgWHBtQ29sb3JTeW1ib2wJY29sb3JbNV0gPQogICAgewoJeyJub25lIiwgTlVMTCwgMH0sCgl7Imljb25Db2xvcjEiLCBOVUxMLCAwfSwKCXsiYm90dG9tU2hhZG93Q29sb3IiLCBOVUxMLCAwfSwKCXsidG9wU2hhZG93Q29sb3IiLCBOVUxMLCAwfSwKCXsic2VsZWN0Q29sb3IiLCBOVUxMLCAwfQogICAgfTsKCiAgICBsYWJlbCA9IFhtQ3JlYXRlTGFiZWxHYWRnZXQocGFyZW50LCBuYW1lLCBhcmdzLCBhcmcpOwoKICAgIC8qCiAgICAgKiBXZSBuZWVkIHRvIGJlIGNhcmVmdWxsIGhlcmUsIHNpbmNlIGluIGNhc2Ugb2YgZ2FkZ2V0cywgdGhlcmUgaXMKICAgICAqIG5vIHdheSB0byBnZXQgdGhlIGJhY2tncm91bmQgY29sb3IgZGlyZWN0bHkgZnJvbSB0aGUgd2lkZ2V0IGl0c2VsZi4KICAgICAqIEluIHN1Y2ggY2FzZXMgd2UgZ2V0IGl0IGZyb20gVGhlIENvcmUgcGFydCBvZiBoaXMgcGFyZW50IGluc3RlYWQuCiAgICAgKi8KICAgIGRzcCA9IFh0RGlzcGxheU9mT2JqZWN0KGxhYmVsKTsKICAgIHNjciA9IFh0U2NyZWVuT2ZPYmplY3QobGFiZWwpOwogICAgWHRWYUdldFZhbHVlcyhYdElzU3ViY2xhc3MobGFiZWwsIGNvcmVXaWRnZXRDbGFzcykKCSAgICA/ICBsYWJlbCA6IFh0UGFyZW50KGxhYmVsKSwKCQkgIFhtTmRlcHRoLCAmZGVwdGgsCgkJICBYbU5iYWNrZ3JvdW5kLCAmY29sb3JbMF0ucGl4ZWwsCgkJICBYbU5mb3JlZ3JvdW5kLCAmY29sb3JbMV0ucGl4ZWwsCgkJICBYbU5ib3R0b21TaGFkb3dDb2xvciwgJmNvbG9yWzJdLnBpeGVsLAoJCSAgWG1OdG9wU2hhZG93Q29sb3IsICZjb2xvclszXS5waXhlbCwKCQkgIFhtTmhpZ2hsaWdodCwgJmNvbG9yWzRdLnBpeGVsLAoJCSAgTlVMTCk7CgogICAgYXR0ci52YWx1ZW1hc2sgPSBYcG1Db2xvclN5bWJvbHMgfCBYcG1DbG9zZW5lc3MgfCBYcG1EZXB0aDsKICAgIGF0dHIuY29sb3JzeW1ib2xzID0gY29sb3I7CiAgICBhdHRyLm51bXN5bWJvbHMgPSA1OwogICAgYXR0ci5jbG9zZW5lc3MgPSA2NTUzNTsKICAgIGF0dHIuZGVwdGggPSBkZXB0aDsKICAgIFhwbUNyZWF0ZVBpeG1hcEZyb21EYXRhKGRzcCwgUm9vdFdpbmRvd09mU2NyZWVuKHNjciksCgkJICAgIGRhdGEsICZwaXhtYXAsIE5VTEwsICZhdHRyKTsKCiAgICBYdFZhR2V0VmFsdWVzKGxhYmVsLCBYbU5yZWNvbXB1dGVTaXplLCAmcnMsIE5VTEwpOwogICAgWHRWYVNldFZhbHVlcyhsYWJlbCwgWG1OcmVjb21wdXRlU2l6ZSwgVHJ1ZSwgTlVMTCk7CiAgICBYdFZhU2V0VmFsdWVzKGxhYmVsLAoJICAgIFhtTmxhYmVsVHlwZSwgWG1QSVhNQVAsCgkgICAgWG1ObGFiZWxQaXhtYXAsIHBpeG1hcCwKCSAgICBOVUxMKTsKICAgIFh0VmFTZXRWYWx1ZXMobGFiZWwsIFhtTnJlY29tcHV0ZVNpemUsIHJzLCBOVUxMKTsKCiAgICByZXR1cm4gbGFiZWw7Cn0KI2VuZGlmCgovKiBBUkdTVVNFRCAqLwogICAgaW50Cmd1aV9tY2hfZGlhbG9nKHR5cGUsIHRpdGxlLCBtZXNzYWdlLCBidXR0b25fbmFtZXMsIGRmbHRidXR0b24sIHRleHRmaWVsZCkKICAgIGludAkJdHlwZTsKICAgIGNoYXJfdQkqdGl0bGU7CiAgICBjaGFyX3UJKm1lc3NhZ2U7CiAgICBjaGFyX3UJKmJ1dHRvbl9uYW1lczsKICAgIGludAkJZGZsdGJ1dHRvbjsKICAgIGNoYXJfdQkqdGV4dGZpZWxkOwkJLyogYnVmZmVyIG9mIHNpemUgSU9TSVpFICovCnsKICAgIGNoYXJfdQkJKmJ1dHM7CiAgICBjaGFyX3UJCSpwLCAqbmV4dDsKICAgIFh0QXBwQ29udGV4dAlhcHA7CiAgICBYbVN0cmluZwkJbGFiZWw7CiAgICBpbnQJCQlidXRjb3VudDsKICAgIFdpZGdldAkJdzsKICAgIFdpZGdldAkJZGlhbG9nZm9ybSA9IE5VTEw7CiAgICBXaWRnZXQJCWZvcm0gPSBOVUxMOwogICAgV2lkZ2V0CQlkaWFsb2d0ZXh0ZmllbGQgPSBOVUxMOwogICAgV2lkZ2V0CQkqYnV0dG9uczsKICAgIFdpZGdldAkJc2VwX2Zvcm0gPSBOVUxMOwogICAgQm9vbGVhbgkJdmVydGljYWw7CiAgICBXaWRnZXQJCXNlcGFyYXRvciA9IE5VTEw7CiAgICBpbnQJCQluOwogICAgQXJnCQkJYXJnc1s2XTsKI2lmZGVmIEhBVkVfWFBNCiAgICBjaGFyCQkqKmljb25fZGF0YSA9IE5VTEw7CiAgICBXaWRnZXQJCWRpYWxvZ3BpeG1hcCA9IE5VTEw7CiNlbmRpZgoKICAgIGlmICh0aXRsZSA9PSBOVUxMKQoJdGl0bGUgPSAoY2hhcl91ICopXygiVmltIGRpYWxvZyIpOwoKICAgIC8qIGlmIG91ciBwb2ludGVyIGlzIGN1cnJlbnRseSBoaWRkZW4sIHRoZW4gd2Ugc2hvdWxkIHNob3cgaXQuICovCiAgICBndWlfbWNoX21vdXNlaGlkZShGQUxTRSk7CgogICAgZGlhbG9nZm9ybSA9IFhtQ3JlYXRlRm9ybURpYWxvZyh2aW1TaGVsbCwgKGNoYXIgKikiZGlhbG9nIiwgTlVMTCwgMCk7CgogICAgLyogQ2hlY2sgJ3YnIGZsYWcgaW4gJ2d1aW9wdGlvbnMnOiB2ZXJ0aWNhbCBidXR0b24gcGxhY2VtZW50LiAqLwogICAgdmVydGljYWwgPSAodmltX3N0cmNocihwX2dvLCBHT19WRVJUSUNBTCkgIT0gTlVMTCk7CgogICAgLyogU2V0IHRoZSB0aXRsZSBvZiB0aGUgRGlhbG9nIHdpbmRvdyAqLwogICAgbGFiZWwgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZSgoY2hhciAqKXRpdGxlKTsKICAgIGlmIChsYWJlbCA9PSBOVUxMKQoJcmV0dXJuIC0xOwogICAgWHRWYVNldFZhbHVlcyhkaWFsb2dmb3JtLAoJICAgIFhtTmRpYWxvZ1RpdGxlLCBsYWJlbCwKCSAgICBYbU5ob3Jpem9udGFsU3BhY2luZywgNCwKCSAgICBYbU52ZXJ0aWNhbFNwYWNpbmcsIHZlcnRpY2FsID8gMCA6IDQsCgkgICAgTlVMTCk7CiAgICBYbVN0cmluZ0ZyZWUobGFiZWwpOwoKICAgIC8qIG1ha2UgYSBjb3B5LCBzbyB0aGF0IHdlIGNhbiBpbnNlcnQgTlVMcyAqLwogICAgYnV0cyA9IHZpbV9zdHJzYXZlKGJ1dHRvbl9uYW1lcyk7CiAgICBpZiAoYnV0cyA9PSBOVUxMKQoJcmV0dXJuIC0xOwoKICAgIC8qIENvdW50IHRoZSBudW1iZXIgb2YgYnV0dG9ucyBhbmQgYWxsb2NhdGUgYnV0dG9uc1tdLiAqLwogICAgYnV0Y291bnQgPSAxOwogICAgZm9yIChwID0gYnV0czsgKnA7ICsrcCkKCWlmICgqcCA9PSBETEdfQlVUVE9OX1NFUCkKCSAgICArK2J1dGNvdW50OwogICAgYnV0dG9ucyA9IChXaWRnZXQgKilhbGxvYygodW5zaWduZWQpKGJ1dGNvdW50ICogc2l6ZW9mKFdpZGdldCkpKTsKICAgIGlmIChidXR0b25zID09IE5VTEwpCiAgICB7Cgl2aW1fZnJlZShidXRzKTsKCXJldHVybiAtMTsKICAgIH0KCiAgICAvKgogICAgICogQ3JlYXRlIHRoZSBidXR0b25zLgogICAgICovCiAgICBzZXBfZm9ybSA9IChXaWRnZXQpIDA7CiAgICBwID0gYnV0czsKICAgIGZvciAoYnV0Y291bnQgPSAwOyAqcDsgKytidXRjb3VudCkKICAgIHsKCUtleVN5bSBtbmVtb25pYyA9IE5VTDsKCglmb3IgKG5leHQgPSBwOyAqbmV4dDsgKytuZXh0KQoJewoJICAgIGlmICgqbmV4dCA9PSBETEdfSE9US0VZX0NIQVIpCgkgICAgewoJCWludCBsZW4gPSBTVFJMRU4obmV4dCk7CgoJCWlmIChsZW4gPiAwKQoJCXsKCQkgICAgbWNoX21lbW1vdmUobmV4dCwgbmV4dCArIDEsIGxlbik7CgkJICAgIG1uZW1vbmljID0gbmV4dFswXTsKCQl9CgkgICAgfQoJICAgIGlmICgqbmV4dCA9PSBETEdfQlVUVE9OX1NFUCkKCSAgICB7CgkJKm5leHQrKyA9IE5VTDsKCQlicmVhazsKCSAgICB9Cgl9CglsYWJlbCA9IFhtU3RyaW5nQ3JlYXRlKF8oKGNoYXIgKilwKSwgU1RSSU5HX1RBRyk7CglpZiAobGFiZWwgPT0gTlVMTCkKCSAgICBicmVhazsKCglidXR0b25zW2J1dGNvdW50XSA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJidXR0b24iLAoJCXhtUHVzaEJ1dHRvbldpZGdldENsYXNzLCBkaWFsb2dmb3JtLAoJCVhtTmxhYmVsU3RyaW5nLCBsYWJlbCwKCQlYbU5tbmVtb25pYywgbW5lbW9uaWMsCgkJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5ib3R0b21PZmZzZXQsIDQsCgkJWG1Oc2hvd0FzRGVmYXVsdCwgYnV0Y291bnQgPT0gZGZsdGJ1dHRvbiAtIDEsCgkJWG1OZGVmYXVsdEJ1dHRvblNoYWRvd1RoaWNrbmVzcywgMSwKCQlOVUxMKTsKCVhtU3RyaW5nRnJlZShsYWJlbCk7CglndWlfbW90aWZfbWVudV9mb250bGlzdChidXR0b25zW2J1dGNvdW50XSk7CgoJLyogTGF5b3V0IHByb3Blcmx5LiAqLwoKCWlmIChidXRjb3VudCA+IDApCgl7CgkgICAgaWYgKHZlcnRpY2FsKQoJCVh0VmFTZXRWYWx1ZXMoYnV0dG9uc1tidXRjb3VudF0sCgkJCVhtTnRvcFdpZGdldCwgYnV0dG9uc1tidXRjb3VudCAtIDFdLAoJCQlOVUxMKTsKCSAgICBlbHNlCgkgICAgewoJCWlmICgqbmV4dCA9PSBOVUwpCgkJewoJCSAgICBYdFZhU2V0VmFsdWVzKGJ1dHRvbnNbYnV0Y291bnRdLAoJCQkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCQkgICAgWG1OcmlnaHRPZmZzZXQsIDQsCgkJCSAgICBOVUxMKTsKCgkJICAgIC8qIGZpbGwgaW4gYSBmb3JtIGFzIGludmlzaWJsZSBzZXBhcmF0b3IgKi8KCQkgICAgc2VwX2Zvcm0gPSBYdFZhQ3JlYXRlV2lkZ2V0KCJzZXBhcmF0b3JGb3JtIiwKCQkJICAgIHhtRm9ybVdpZGdldENsYXNzLAlkaWFsb2dmb3JtLAoJCQkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgIFhtTmxlZnRXaWRnZXQsIGJ1dHRvbnNbYnV0Y291bnQgLSAxXSwKCQkJICAgIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgWG1OcmlnaHRXaWRnZXQsIGJ1dHRvbnNbYnV0Y291bnRdLAoJCQkgICAgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJICAgIFhtTmJvdHRvbU9mZnNldCwgNCwKCQkJICAgIE5VTEwpOwoJCSAgICBYdE1hbmFnZUNoaWxkKHNlcF9mb3JtKTsKCQl9CgkJZWxzZQoJCXsKCQkgICAgWHRWYVNldFZhbHVlcyhidXR0b25zW2J1dGNvdW50XSwKCQkJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICBYbU5sZWZ0V2lkZ2V0LCBidXR0b25zW2J1dGNvdW50IC0gMV0sCgkJCSAgICBOVUxMKTsKCQl9CgkgICAgfQoJfQoJZWxzZSBpZiAoIXZlcnRpY2FsKQoJewoJICAgIGlmICgqbmV4dCA9PSBOVUwpCgkgICAgewoJCVh0VmFTZXRWYWx1ZXMoYnV0dG9uc1swXSwKCQkJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCQlYbU5yaWdodE9mZnNldCwgNCwKCQkJTlVMTCk7CgoJCS8qIGZpbGwgaW4gYSBmb3JtIGFzIGludmlzaWJsZSBzZXBhcmF0b3IgKi8KCQlzZXBfZm9ybSA9IFh0VmFDcmVhdGVXaWRnZXQoInNlcGFyYXRvckZvcm0iLAoJCQl4bUZvcm1XaWRnZXRDbGFzcywgZGlhbG9nZm9ybSwKCQkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCVhtTmxlZnRPZmZzZXQsIDQsCgkJCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQlYbU5yaWdodFdpZGdldCwgYnV0dG9uc1swXSwKCQkJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJWG1OYm90dG9tT2Zmc2V0LCA0LAoJCQlOVUxMKTsKCQlYdE1hbmFnZUNoaWxkKHNlcF9mb3JtKTsKCSAgICB9CgkgICAgZWxzZQoJCVh0VmFTZXRWYWx1ZXMoYnV0dG9uc1swXSwKCQkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCVhtTmxlZnRPZmZzZXQsIDQsCgkJCU5VTEwpOwoJfQoKCVh0QWRkQ2FsbGJhY2soYnV0dG9uc1tidXRjb3VudF0sIFhtTmFjdGl2YXRlQ2FsbGJhY2ssCgkJCSAgKFh0Q2FsbGJhY2tQcm9jKWJ1dHByb2MsIChYdFBvaW50ZXIpKGxvbmcpYnV0Y291bnQpOwoJcCA9IG5leHQ7CiAgICB9CiAgICB2aW1fZnJlZShidXRzKTsKCiAgICBzZXBhcmF0b3IgPSAoV2lkZ2V0KSAwOwogICAgaWYgKGJ1dGNvdW50ID4gMCkKICAgIHsKCS8qIENyZWF0ZSB0aGUgc2VwYXJhdG9yIGZvciBiZWF1dHkuICovCgluID0gMDsKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm9yaWVudGF0aW9uLCBYbUhPUklaT05UQUwpOyBuKys7CglYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQpOyBuKys7CglYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21XaWRnZXQsIGJ1dHRvbnNbMF0pOyBuKys7CglYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21PZmZzZXQsIDQpOyBuKys7CglYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCXNlcGFyYXRvciA9IFhtQ3JlYXRlU2VwYXJhdG9yR2FkZ2V0KGRpYWxvZ2Zvcm0sICJzZXBhcmF0b3IiLCBhcmdzLCBuKTsKCVh0TWFuYWdlQ2hpbGQoc2VwYXJhdG9yKTsKICAgIH0KCiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwpCiAgICB7CglkaWFsb2d0ZXh0ZmllbGQgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJ0ZXh0RmllbGQiLAoJCXhtVGV4dEZpZWxkV2lkZ2V0Q2xhc3MsIGRpYWxvZ2Zvcm0sCgkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCU5VTEwpOwoJaWYgKGJ1dGNvdW50ID4gMCkKCSAgICBYdFZhU2V0VmFsdWVzKGRpYWxvZ3RleHRmaWVsZCwKCQkgICAgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCSAgICBYbU5ib3R0b21XaWRnZXQsIHNlcGFyYXRvciwKCQkgICAgTlVMTCk7CgllbHNlCgkgICAgWHRWYVNldFZhbHVlcyhkaWFsb2d0ZXh0ZmllbGQsCgkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIE5VTEwpOwoKCXNldF9mb250bGlzdChkaWFsb2d0ZXh0ZmllbGQpOwoJWG1UZXh0RmllbGRTZXRTdHJpbmcoZGlhbG9ndGV4dGZpZWxkLCAoY2hhciAqKXRleHRmaWVsZCk7CglYdE1hbmFnZUNoaWxkKGRpYWxvZ3RleHRmaWVsZCk7CglYdEFkZEV2ZW50SGFuZGxlcihkaWFsb2d0ZXh0ZmllbGQsIEtleVByZXNzTWFzaywgRmFsc2UsCgkJCSAgICAoWHRFdmVudEhhbmRsZXIpa2V5aGl0X2NhbGxiYWNrLCAoWHRQb2ludGVyKU5VTEwpOwogICAgfQoKICAgIC8qIEZvcm0gaG9sZGluZyBib3RoIG1lc3NhZ2UgYW5kIHBpeG1hcCBsYWJlbHMgKi8KICAgIGZvcm0gPSBYdFZhQ3JlYXRlV2lkZ2V0KCJzZXBhcmF0b3JGb3JtIiwKCSAgICB4bUZvcm1XaWRnZXRDbGFzcywgZGlhbG9nZm9ybSwKCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBOVUxMKTsKICAgIFh0TWFuYWdlQ2hpbGQoZm9ybSk7CgojaWZkZWYgSEFWRV9YUE0KICAgIC8qIEFkZCBhIHBpeG1hcCwgbGVmdCBvZiB0aGUgbWVzc2FnZS4gKi8KICAgIHN3aXRjaCAodHlwZSkKICAgIHsKCWNhc2UgVklNX0dFTkVSSUM6CgkgICAgaWNvbl9kYXRhID0gZ2VuZXJpY194cG07CgkgICAgYnJlYWs7CgljYXNlIFZJTV9FUlJPUjoKCSAgICBpY29uX2RhdGEgPSBlcnJvcl94cG07CgkgICAgYnJlYWs7CgljYXNlIFZJTV9XQVJOSU5HOgoJICAgIGljb25fZGF0YSA9IGFsZXJ0X3hwbTsKCSAgICBicmVhazsKCWNhc2UgVklNX0lORk86CgkgICAgaWNvbl9kYXRhID0gaW5mb194cG07CgkgICAgYnJlYWs7CgljYXNlIFZJTV9RVUVTVElPTjoKCSAgICBpY29uX2RhdGEgPSBxdWVzdF94cG07CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIGljb25fZGF0YSA9IGdlbmVyaWNfeHBtOwogICAgfQoKICAgIG4gPSAwOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnRvcE9mZnNldCwgOCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21PZmZzZXQsIDgpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxlZnRPZmZzZXQsIDgpOyBuKys7CgogICAgZGlhbG9ncGl4bWFwID0gY3JlYXRlX3BpeG1hcF9sYWJlbChmb3JtLCAiZGlhbG9nUGl4bWFwIiwKCSAgICBpY29uX2RhdGEsIGFyZ3MsIG4pOwogICAgWHRNYW5hZ2VDaGlsZChkaWFsb2dwaXhtYXApOwojZW5kaWYKCiAgICAvKiBDcmVhdGUgdGhlIGRpYWxvZyBtZXNzYWdlLgogICAgICogU2luY2UgTGVzc1RpZiBpcyBhcHBhcmVudGx5IGhhdmluZyBwcm9ibGVtcyB3aXRoIHRoZSBjcmVhdGlvbiBvZgogICAgICogcHJvcGVybHkgbG9jYWxpemVkIHN0cmluZywgd2UgdXNlIEx0b1IgaGVyZS4gVGhlIHN5bXB0b20gaXMgdGhhdCB0aGUKICAgICAqIHN0cmluZyBzaWxsIG5vdCBzaG93IHByb3Blcmx5IGluIG11bHRpcGxlIGxpbmVzIGFzIGl0IGRvZXMgaW4gbmF0aXZlCiAgICAgKiBNb3RpZi4KICAgICAqLwogICAgbGFiZWwgPSBYbVN0cmluZ0NyZWF0ZUx0b1IoKGNoYXIgKiltZXNzYWdlLCBTVFJJTkdfVEFHKTsKICAgIGlmIChsYWJlbCA9PSBOVUxMKQoJcmV0dXJuIC0xOwogICAgdyA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJkaWFsb2dNZXNzYWdlIiwKCQkJCXhtTGFiZWxHYWRnZXRDbGFzcywgZm9ybSwKCQkJCVhtTmxhYmVsU3RyaW5nLCBsYWJlbCwKCQkJCVhtTmFsaWdubWVudCwgWG1BTElHTk1FTlRfQkVHSU5OSU5HLAoJCQkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJCVhtTnRvcE9mZnNldCwgOCwKI2lmZGVmIEhBVkVfWFBNCgkJCQlYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkJWG1ObGVmdFdpZGdldCwgZGlhbG9ncGl4bWFwLAojZWxzZQoJCQkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCiNlbmRpZgoJCQkJWG1ObGVmdE9mZnNldCwgOCwKCQkJCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJCVhtTnJpZ2h0T2Zmc2V0LCA4LAoJCQkJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJCVhtTmJvdHRvbU9mZnNldCwgOCwKCQkJCU5VTEwpOwogICAgWG1TdHJpbmdGcmVlKGxhYmVsKTsKICAgIHNldF9mb250bGlzdCh3KTsKCiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwpCiAgICB7CglYdFZhU2V0VmFsdWVzKGZvcm0sCgkJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCVhtTmJvdHRvbVdpZGdldCwgZGlhbG9ndGV4dGZpZWxkLAoJCU5VTEwpOwogICAgfQogICAgZWxzZQogICAgewoJaWYgKGJ1dGNvdW50ID4gMCkKCSAgICBYdFZhU2V0VmFsdWVzKGZvcm0sCgkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkgICAgWG1OYm90dG9tV2lkZ2V0LCBzZXBhcmF0b3IsCgkJICAgIE5VTEwpOwoJZWxzZQoJICAgIFh0VmFTZXRWYWx1ZXMoZm9ybSwKCQkgICAgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkgICAgTlVMTCk7CiAgICB9CgogICAgaWYgKGRmbHRidXR0b24gPCAxKQoJZGZsdGJ1dHRvbiA9IDE7CiAgICBpZiAoZGZsdGJ1dHRvbiA+IGJ1dGNvdW50KQoJZGZsdGJ1dHRvbiA9IGJ1dGNvdW50OwogICAgWHRWYVNldFZhbHVlcyhkaWFsb2dmb3JtLAoJICAgIFhtTmRlZmF1bHRCdXR0b24sIGJ1dHRvbnNbZGZsdGJ1dHRvbiAtIDFdLCBOVUxMKTsKICAgIGlmICh0ZXh0ZmllbGQgIT0gTlVMTCkKCVh0VmFTZXRWYWx1ZXMoZGlhbG9nZm9ybSwgWG1OaW5pdGlhbEZvY3VzLCBkaWFsb2d0ZXh0ZmllbGQsIE5VTEwpOwogICAgZWxzZQoJWHRWYVNldFZhbHVlcyhkaWFsb2dmb3JtLCBYbU5pbml0aWFsRm9jdXMsIGJ1dHRvbnNbZGZsdGJ1dHRvbiAtIDFdLAoJCQkJCQkJCQlOVUxMKTsKCiAgICBtYW5hZ2VfY2VudGVyZWQoZGlhbG9nZm9ybSk7CiAgICBhY3RpdmF0ZV9kaWFsb2dfbW5lbW9uaWNzKGRpYWxvZ2Zvcm0pOwoKICAgIGlmICh0ZXh0ZmllbGQgIT0gTlVMTCAmJiAqdGV4dGZpZWxkICE9IE5VTCkKICAgIHsKCS8qIFRoaXMgb25seSB3b3JrcyBhZnRlciB0aGUgdGV4dGZpZWxkIGhhcyBiZWVuIHJlYWxpc2VkLiAqLwoJWG1UZXh0RmllbGRTZXRTZWxlY3Rpb24oZGlhbG9ndGV4dGZpZWxkLAoJCQkgKFhtVGV4dFBvc2l0aW9uKTAsIChYbVRleHRQb3NpdGlvbilTVFJMRU4odGV4dGZpZWxkKSwKCQkJCQkgICBYdExhc3RUaW1lc3RhbXBQcm9jZXNzZWQoZ3VpLmRweSkpOwoJWG1UZXh0RmllbGRTZXRDdXJzb3JQb3NpdGlvbihkaWFsb2d0ZXh0ZmllbGQsCgkJCQkJICAgKFhtVGV4dFBvc2l0aW9uKVNUUkxFTih0ZXh0ZmllbGQpKTsKICAgIH0KCiAgICBhcHAgPSBYdFdpZGdldFRvQXBwbGljYXRpb25Db250ZXh0KGRpYWxvZ2Zvcm0pOwoKICAgIC8qIExvb3AgdW50aWwgYSBidXR0b24gaXMgcHJlc3NlZCBvciB0aGUgZGlhbG9nIGlzIGtpbGxlZCBzb21laG93LiAqLwogICAgZGlhbG9nU3RhdHVzID0gLTE7CiAgICBmb3IgKDs7KQogICAgewoJWHRBcHBQcm9jZXNzRXZlbnQoYXBwLCAoWHRJbnB1dE1hc2spWHRJTUFsbCk7CglpZiAoZGlhbG9nU3RhdHVzID49IDAgfHwgIVh0SXNNYW5hZ2VkKGRpYWxvZ2Zvcm0pKQoJICAgIGJyZWFrOwogICAgfQoKICAgIHZpbV9mcmVlKGJ1dHRvbnMpOwoKICAgIGlmICh0ZXh0ZmllbGQgIT0gTlVMTCkKICAgIHsKCXAgPSAoY2hhcl91ICopWG1UZXh0R2V0U3RyaW5nKGRpYWxvZ3RleHRmaWVsZCk7CglpZiAocCA9PSBOVUxMIHx8IGRpYWxvZ1N0YXR1cyA8IDApCgkgICAgKnRleHRmaWVsZCA9IE5VTDsKCWVsc2UKCXsKCSAgICBTVFJOQ1BZKHRleHRmaWVsZCwgcCwgSU9TSVpFKTsKCSAgICB0ZXh0ZmllbGRbSU9TSVpFIC0gMV0gPSBOVUw7Cgl9CiAgICB9CgogICAgc3VwcHJlc3NfZGlhbG9nX21uZW1vbmljcyhkaWFsb2dmb3JtKTsKICAgIFh0RGVzdHJveVdpZGdldChkaWFsb2dmb3JtKTsKCiAgICByZXR1cm4gZGlhbG9nU3RhdHVzOwp9CiNlbmRpZiAvKiBGRUFUX0dVSV9ESUFMT0cgKi8KCiNpZiBkZWZpbmVkKEZFQVRfRk9PVEVSKSB8fCBkZWZpbmVkKFBST1RPKQoKICAgIHN0YXRpYyBpbnQKZ3VpX21jaF9jb21wdXRlX2Zvb3Rlcl9oZWlnaHQoKQp7CiAgICBEaW1lbnNpb24JaGVpZ2h0OwkJICAgIC8qIHRvdGFsIFRvb2xiYXIgaGVpZ2h0ICovCiAgICBEaW1lbnNpb24JdG9wOwkJICAgIC8qIFhtTm1hcmdpblRvcCAqLwogICAgRGltZW5zaW9uCWJvdHRvbTsJCSAgICAvKiBYbU5tYXJnaW5Cb3R0b20gKi8KICAgIERpbWVuc2lvbglzaGFkb3c7CQkgICAgLyogWG1Oc2hhZG93VGhpY2tuZXNzICovCgogICAgWHRWYUdldFZhbHVlcyhmb290ZXIsCgkgICAgWG1OaGVpZ2h0LCAmaGVpZ2h0LAoJICAgIFhtTm1hcmdpblRvcCwgJnRvcCwKCSAgICBYbU5tYXJnaW5Cb3R0b20sICZib3R0b20sCgkgICAgWG1Oc2hhZG93VGhpY2tuZXNzLCAmc2hhZG93LAoJICAgIE5VTEwpOwoKICAgIHJldHVybiAoaW50KSBoZWlnaHQgKyB0b3AgKyBib3R0b20gKyAoc2hhZG93IDw8IDEpOwp9CgojaWYgMAkgICAgLyogbm90IHVzZWQgKi8KICAgIHZvaWQKZ3VpX21jaF9zZXRfZm9vdGVyX3BvcyhoKQogICAgaW50CSAgICBoOwkJCSAgICAvKiB0ZXh0QXJlYSBoZWlnaHQgKi8KewogICAgWHRWYVNldFZhbHVlcyhmb290ZXIsCgkJICBYbU50b3BPZmZzZXQsIGggKyA3LAoJCSAgTlVMTCk7Cn0KI2VuZGlmCgogICAgdm9pZApndWlfbWNoX2VuYWJsZV9mb290ZXIoc2hvd2l0KQogICAgaW50CQlzaG93aXQ7CnsKICAgIGlmIChzaG93aXQpCiAgICB7CglndWkuZm9vdGVyX2hlaWdodCA9IGd1aV9tY2hfY29tcHV0ZV9mb290ZXJfaGVpZ2h0KCk7CglYdE1hbmFnZUNoaWxkKGZvb3Rlcik7CiAgICB9CiAgICBlbHNlCiAgICB7CglndWkuZm9vdGVyX2hlaWdodCA9IDA7CglYdFVubWFuYWdlQ2hpbGQoZm9vdGVyKTsKICAgIH0KICAgIFh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLCBYbU5ib3R0b21PZmZzZXQsIGd1aS5mb290ZXJfaGVpZ2h0LCBOVUxMKTsKfQoKICAgIHZvaWQKZ3VpX21jaF9zZXRfZm9vdGVyKHMpCiAgICBjaGFyX3UJKnM7CnsKICAgIFhtU3RyaW5nCXhtczsKCiAgICB4bXMgPSBYbVN0cmluZ0NyZWF0ZSgoY2hhciAqKXMsIFNUUklOR19UQUcpOwogICAgaWYgKHhtcyAhPSBOVUxMKQogICAgewoJWHRWYVNldFZhbHVlcyhmb290ZXIsIFhtTmxhYmVsU3RyaW5nLCB4bXMsIE5VTEwpOwoJWG1TdHJpbmdGcmVlKHhtcyk7CiAgICB9Cn0KCiNlbmRpZgoKCiNpZiBkZWZpbmVkKEZFQVRfVE9PTEJBUikgfHwgZGVmaW5lZChQUk9UTykKICAgIHZvaWQKZ3VpX21jaF9zaG93X3Rvb2xiYXIoaW50IHNob3dpdCkKewogICAgQ2FyZGluYWwJbnVtQ2hpbGRyZW47CSAgICAvKiBob3cgbWFueSBjaGlsZHJlbiB0b29sQmFyIGhhcyAqLwoKICAgIGlmICh0b29sQmFyID09IChXaWRnZXQpMCkKCXJldHVybjsKICAgIFh0VmFHZXRWYWx1ZXModG9vbEJhciwgWG1ObnVtQ2hpbGRyZW4sICZudW1DaGlsZHJlbiwgTlVMTCk7CiAgICBpZiAoc2hvd2l0ICYmIG51bUNoaWxkcmVuID4gMCkKICAgIHsKCS8qIEFzc3VtZSB0aGF0IHdlIHdhbnQgdG8gc2hvdyB0aGUgdG9vbGJhciBpZiBwX3Rvb2xiYXIgY29udGFpbnMKCSAqIHZhbGlkIG9wdGlvbiBzZXR0aW5ncywgdGhlcmVmb3JlIHBfdG9vbGJhciBtdXN0IG5vdCBiZSBOVUxMLgoJICovCglXaWRnZXRMaXN0ICBjaGlsZHJlbjsKCglYdFZhR2V0VmFsdWVzKHRvb2xCYXIsIFhtTmNoaWxkcmVuLCAmY2hpbGRyZW4sIE5VTEwpOwoJewoJICAgIHZvaWQgICAgKCphY3Rpb24pKEJhbGxvb25FdmFsICopOwoJICAgIGludAkgICAgdGV4dCA9IDA7CgoJICAgIGlmIChzdHJzdHIoKGNvbnN0IGNoYXIgKilwX3Rvb2xiYXIsICJ0b29sdGlwcyIpKQoJCWFjdGlvbiA9ICZndWlfbWNoX2VuYWJsZV9iZXZhbF9hcmVhOwoJICAgIGVsc2UKCQlhY3Rpb24gPSAmZ3VpX21jaF9kaXNhYmxlX2JldmFsX2FyZWE7CgkgICAgaWYgKHN0cnN0cigoY29uc3QgY2hhciAqKXBfdG9vbGJhciwgInRleHQiKSkKCQl0ZXh0ID0gMTsKCSAgICBlbHNlIGlmIChzdHJzdHIoKGNvbnN0IGNoYXIgKilwX3Rvb2xiYXIsICJpY29ucyIpKQoJCXRleHQgPSAtMTsKCSAgICBpZiAodGV4dCAhPSAwKQoJICAgIHsKCQl2aW1tZW51X1QgICAqdG9vbGJhcjsKCQl2aW1tZW51X1QgICAqY3VyOwoKCQlmb3IgKHRvb2xiYXIgPSByb290X21lbnU7IHRvb2xiYXI7IHRvb2xiYXIgPSB0b29sYmFyLT5uZXh0KQoJCSAgICBpZiAobWVudV9pc190b29sYmFyKHRvb2xiYXItPmRuYW1lKSkKCQkJYnJlYWs7CgkJLyogQXNzdW1wdGlvbjogdG9vbGJhciBpcyBOVUxMIGlmIHRoZXJlIGlzIG5vIHRvb2xiYXIsCgkJICoJICAgICAgIG90aGVyd2lzZSBpdCBjb250YWlucyB0aGUgdG9vbGJhciBtZW51IHN0cnVjdHVyZS4KCQkgKgoJCSAqIEFzc3VtcHRpb246ICJudW1DaGlsZHJlbiIgPT0gdGhlIG51bWJlciBvZiBpdGVtcyBpbiB0aGUgbGlzdAoJCSAqCSAgICAgICBvZiBpdGVtcyBiZWdpbm5pbmcgd2l0aCB0b29sYmFyLT5jaGlsZHJlbi4KCQkgKi8KCQlpZiAodG9vbGJhcikKCQl7CgkJICAgIGZvciAoY3VyID0gdG9vbGJhci0+Y2hpbGRyZW47IGN1cjsgY3VyID0gY3VyLT5uZXh0KQoJCSAgICB7CgkJCUFyZwkgICAgYXJnc1sxXTsKCQkJaW50CSAgICBuID0gMDsKCgkJCS8qIEVuYWJsZS9EaXNhYmxlIHRvb2x0aXAgKE9LIHRvIGVuYWJsZSB3aGlsZQoJCQkgKiBjdXJyZW50bHkgZW5hYmxlZCkKCQkJICovCgkJCWlmIChjdXItPnRpcCAhPSBOVUxMKQoJCQkgICAgKCphY3Rpb24pKGN1ci0+dGlwKTsKCQkJaWYgKCFtZW51X2lzX3NlcGFyYXRvcihjdXItPm5hbWUpKQoJCQl7CgkJCSAgICBpZiAodGV4dCA9PSAxIHx8IGN1ci0+eHBtID09IE5VTEwpCgkJCSAgICB7CgkJCQlYdFNldEFyZyhhcmdzW25dLCBYbU5sYWJlbFR5cGUsIFhtU1RSSU5HKTsKCQkJCSsrbjsKCQkJICAgIH0KCQkJICAgIGlmIChjdXItPmlkICE9IE5VTEwpCgkJCSAgICB7CgkJCQlYdFVubWFuYWdlQ2hpbGQoY3VyLT5pZCk7CgkJCQlYdFNldFZhbHVlcyhjdXItPmlkLCBhcmdzLCBuKTsKCQkJCVh0TWFuYWdlQ2hpbGQoY3VyLT5pZCk7CgkJCSAgICB9CgkJCX0KCQkgICAgfQoJCX0KCSAgICB9Cgl9CglndWkudG9vbGJhcl9oZWlnaHQgPSBndWlfbWNoX2NvbXB1dGVfdG9vbGJhcl9oZWlnaHQoKTsKCVh0TWFuYWdlQ2hpbGQoWHRQYXJlbnQodG9vbEJhcikpOwoJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCVhtTnRvcFdpZGdldCwgWHRQYXJlbnQodG9vbEJhciksCgkJTlVMTCk7CglpZiAoWHRJc01hbmFnZWQobWVudUJhcikpCgkgICAgWHRWYVNldFZhbHVlcyhYdFBhcmVudCh0b29sQmFyKSwKCQkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCSAgICBYbU50b3BXaWRnZXQsIG1lbnVCYXIsCgkJICAgIE5VTEwpOwoJZWxzZQoJICAgIFh0VmFTZXRWYWx1ZXMoWHRQYXJlbnQodG9vbEJhciksCgkJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIE5VTEwpOwogICAgfQogICAgZWxzZQogICAgewoJZ3VpLnRvb2xiYXJfaGVpZ2h0ID0gMDsKCWlmIChYdElzTWFuYWdlZChtZW51QmFyKSkKCSAgICBYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQlYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJWG1OdG9wV2lkZ2V0LCBtZW51QmFyLAoJCU5VTEwpOwoJZWxzZQoJICAgIFh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJTlVMTCk7CgoJWHRVbm1hbmFnZUNoaWxkKFh0UGFyZW50KHRvb2xCYXIpKTsKICAgIH0KICAgIGd1aV9zZXRfc2hlbGxzaXplKEZBTFNFLCBGQUxTRSk7Cn0KCi8qCiAqIEEgdG9vbGJhciBidXR0b24gaGFzIGJlZW4gcHVzaGVkOyBub3cgcmVzZXQgdGhlIGlucHV0IGZvY3VzCiAqIHN1Y2ggdGhhdCB0aGUgdXNlciBjYW4gdHlwZSBwYWdlIHVwL2Rvd24gZXRjLiBhbmQgaGF2ZSB0aGUKICogaW5wdXQgZ28gdG8gdGhlIGVkaXRvciB3aW5kb3csIG5vdCB0aGUgYnV0dG9uCiAqLwogICAgc3RhdGljIHZvaWQKcmVzZXRfZm9jdXMoKQp7CiAgICBpZiAodGV4dEFyZWEgIT0gTlVMTCkKCVhtUHJvY2Vzc1RyYXZlcnNhbCh0ZXh0QXJlYSwgWG1UUkFWRVJTRV9DVVJSRU5UKTsKfQoKICAgIGludApndWlfbWNoX2NvbXB1dGVfdG9vbGJhcl9oZWlnaHQoKQp7CiAgICBEaW1lbnNpb24JYm9yZGVyczsKICAgIERpbWVuc2lvbgloZWlnaHQ7CQkgICAgLyogdG90YWwgVG9vbGJhciBoZWlnaHQgKi8KICAgIERpbWVuc2lvbgl3aGd0OwkJICAgIC8qIGhlaWdodCBvZiBlYWNoIHdpZGdldCAqLwogICAgV2lkZ2V0TGlzdAljaGlsZHJlbjsJICAgIC8qIGxpc3Qgb2YgdG9vbEJhcidzIGNoaWxkcmVuICovCiAgICBDYXJkaW5hbAludW1DaGlsZHJlbjsJICAgIC8qIGhvdyBtYW55IGNoaWxkcmVuIHRvb2xCYXIgaGFzICovCiAgICBpbnQJCWk7CgogICAgYm9yZGVycyA9IDA7CiAgICBoZWlnaHQgPSAwOwogICAgaWYgKHRvb2xCYXIgIT0gKFdpZGdldCkwICYmIHRvb2xCYXJGcmFtZSAhPSAoV2lkZ2V0KTApCiAgICB7CQkJCSAgICAvKiBnZXQgaGVpZ2h0IG9mIFhtRnJhbWUgcGFyZW50ICovCglEaW1lbnNpb24JZnN0OwoJRGltZW5zaW9uCWZtaDsKCURpbWVuc2lvbgl0c3Q7CglEaW1lbnNpb24JdG1oOwoKCVh0VmFHZXRWYWx1ZXModG9vbEJhckZyYW1lLAoJCVhtTnNoYWRvd1RoaWNrbmVzcywgJmZzdCwKCQlYbU5tYXJnaW5IZWlnaHQsICZmbWgsCgkJTlVMTCk7Cglib3JkZXJzICs9IGZzdCArIGZtaDsKCVh0VmFHZXRWYWx1ZXModG9vbEJhciwKCQlYbU5zaGFkb3dUaGlja25lc3MsICZ0c3QsCgkJWG1ObWFyZ2luSGVpZ2h0LCAmdG1oLAoJCVhtTmNoaWxkcmVuLCAmY2hpbGRyZW4sCgkJWG1ObnVtQ2hpbGRyZW4sICZudW1DaGlsZHJlbiwgTlVMTCk7Cglib3JkZXJzICs9IHRzdCArIHRtaDsKCWZvciAoaSA9IDA7IGkgPCBudW1DaGlsZHJlbjsgaSsrKQoJewoJICAgIHdoZ3QgPSAwOwoJICAgIFh0VmFHZXRWYWx1ZXMoY2hpbGRyZW5baV0sIFhtTmhlaWdodCwgJndoZ3QsIE5VTEwpOwoJICAgIGlmIChoZWlnaHQgPCB3aGd0KQoJCWhlaWdodCA9IHdoZ3Q7Cgl9CiAgICB9CiNpZmRlZiBMRVNTVElGX1ZFUlNJT04KICAgIC8qIEhhY2s6IFdoZW4gc3RhcnRpbmcgdXAgd2UgZ2V0IHdyb25nIGRpbWVuc2lvbnMuICovCiAgICBpZiAoaGVpZ2h0IDwgMTApCgloZWlnaHQgPSAyNDsKI2VuZGlmCgogICAgcmV0dXJuIChpbnQpKGhlaWdodCArIChib3JkZXJzIDw8IDEpKTsKfQoKICAgIHZvaWQKbW90aWZfZ2V0X3Rvb2xiYXJfY29sb3JzKGJncCwgZmdwLCBic3AsIHRzcCwgaHNwKQogICAgUGl4ZWwgICAgICAgKmJncDsKICAgIFBpeGVsICAgICAgICpmZ3A7CiAgICBQaXhlbCAgICAgICAqYnNwOwogICAgUGl4ZWwgICAgICAgKnRzcDsKICAgIFBpeGVsICAgICAgICpoc3A7CnsKICAgIFh0VmFHZXRWYWx1ZXModG9vbEJhciwKICAgICAgICAgICAgWG1OYmFja2dyb3VuZCwgYmdwLAogICAgICAgICAgICBYbU5mb3JlZ3JvdW5kLCBmZ3AsCiAgICAgICAgICAgIFhtTmJvdHRvbVNoYWRvd0NvbG9yLCBic3AsCiAgICAgICAgICAgIFhtTnRvcFNoYWRvd0NvbG9yLCB0c3AsCiAgICAgICAgICAgIFhtTmhpZ2hsaWdodENvbG9yLCBoc3AsCiAgICAgICAgICAgIE5VTEwpOwp9CgojIGlmZGVmIEZFQVRfRk9PVEVSCi8qCiAqIFRoZSBuZXh0IHRvb2xiYXIgZW50ZXIvbGVhdmUgY2FsbGJhY2tzIHNob3VsZCByZWFsbHkgZG8gYmFsbG9vbiBoZWxwLiAgQnV0CiAqIEkgaGF2ZSB0byB1c2UgZm9vdGVyIGhlbHAgZm9yIGJhY2t3YXJkcyBjb21wYXRhYmlsaXR5LiAgSG9wZWZ1bGx5IGJvdGggd2lsbAogKiBnZXQgaW1wbGVtZW50ZWQgYW5kIHRoZSB1c2VyIHdpbGwgaGF2ZSBhIGNob2ljZS4KICovCi8qQVJHU1VTRUQqLwogICAgc3RhdGljIHZvaWQKdG9vbGJhcmJ1dHRvbl9lbnRlcl9jYih3LCBjbGllbnRfZGF0YSwgZXZlbnQsIGNvbnQpCiAgICBXaWRnZXQJdzsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsKICAgIFhFdmVudAkqZXZlbnQ7CiAgICBCb29sZWFuCSpjb250Owp7CiAgICB2aW1tZW51X1QJKm1lbnUgPSAodmltbWVudV9UICopIGNsaWVudF9kYXRhOwoKICAgIGlmIChtZW51LT5zdHJpbmdzW01FTlVfSU5ERVhfVElQXSAhPSBOVUxMKQogICAgewoJaWYgKHZpbV9zdHJjaHIocF9nbywgR09fRk9PVEVSKSAhPSBOVUxMKQoJICAgIGd1aV9tY2hfc2V0X2Zvb3RlcihtZW51LT5zdHJpbmdzW01FTlVfSU5ERVhfVElQXSk7CiAgICB9Cn0KCi8qQVJHU1VTRUQqLwogICAgc3RhdGljIHZvaWQKdG9vbGJhcmJ1dHRvbl9sZWF2ZV9jYih3LCBjbGllbnRfZGF0YSwgZXZlbnQsIGNvbnQpCiAgICBXaWRnZXQJdzsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsKICAgIFhFdmVudAkqZXZlbnQ7CiAgICBCb29sZWFuCSpjb250Owp7CiAgICBndWlfbWNoX3NldF9mb290ZXIoKGNoYXJfdSAqKSAiIik7Cn0KIyBlbmRpZgojZW5kaWYKCi8qCiAqIFNldCB0aGUgY29sb3JzIG9mIFdpZGdldCAiaWQiIHRvIHRoZSBtZW51IGNvbG9ycy4KICovCiAgICBzdGF0aWMgdm9pZApndWlfbW90aWZfbWVudV9jb2xvcnMoaWQpCiAgICBXaWRnZXQgIGlkOwp7CiAgICBpZiAoZ3VpLm1lbnVfYmdfcGl4ZWwgIT0gSU5WQUxDT0xPUikKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKCVhtQ2hhbmdlQ29sb3IoaWQsIGd1aS5tZW51X2JnX3BpeGVsKTsKI2Vsc2UKCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmJhY2tncm91bmQsIGd1aS5tZW51X2JnX3BpeGVsLCBOVUxMKTsKI2VuZGlmCiAgICBpZiAoZ3VpLm1lbnVfZmdfcGl4ZWwgIT0gSU5WQUxDT0xPUikKCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvcmVncm91bmQsIGd1aS5tZW51X2ZnX3BpeGVsLCBOVUxMKTsKfQoKLyoKICogU2V0IHRoZSBjb2xvcnMgb2YgV2lkZ2V0ICJpZCIgdG8gdGhlIHNjcm9sbGJhciBjb2xvcnMuCiAqLwogICAgc3RhdGljIHZvaWQKZ3VpX21vdGlmX3Njcm9sbF9jb2xvcnMoaWQpCiAgICBXaWRnZXQgIGlkOwp7CiAgICBpZiAoZ3VpLnNjcm9sbF9iZ19waXhlbCAhPSBJTlZBTENPTE9SKQojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJWG1DaGFuZ2VDb2xvcihpZCwgZ3VpLnNjcm9sbF9iZ19waXhlbCk7CiNlbHNlCglYdFZhU2V0VmFsdWVzKGlkLCBYbU5iYWNrZ3JvdW5kLCBndWkuc2Nyb2xsX2JnX3BpeGVsLCBOVUxMKTsKI2VuZGlmCiAgICBpZiAoZ3VpLnNjcm9sbF9mZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJWHRWYVNldFZhbHVlcyhpZCwgWG1OZm9yZWdyb3VuZCwgZ3VpLnNjcm9sbF9mZ19waXhlbCwgTlVMTCk7Cn0KCi8qCiAqIFNldCB0aGUgZm9udGxpc3QgZm9yIFdpZGdldCAiaWQiIHRvIHVzZSBndWkubWVudV9mb250c2V0IG9yIGd1aS5tZW51X2ZvbnQuCiAqLwovKkFSR1NVU0VEKi8KICAgIHZvaWQKZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoaWQpCiAgICBXaWRnZXQgIGlkOwp7CiNpZmRlZiBGRUFUX01FTlUKI2lmZGVmIEZPTlRTRVRfQUxXQVlTCiAgICBpZiAoZ3VpLm1lbnVfZm9udHNldCAhPSBOT0ZPTlRTRVQpCiAgICB7CglYbUZvbnRMaXN0IGZsOwoKCWZsID0gZ3VpX21vdGlmX2ZvbnRzZXQyZm9udGxpc3QoKFhGb250U2V0ICopJmd1aS5tZW51X2ZvbnRzZXQpOwoJaWYgKGZsICE9IE5VTEwpCgl7CgkgICAgaWYgKFh0SXNNYW5hZ2VkKGlkKSkKCSAgICB7CgkJWHRVbm1hbmFnZUNoaWxkKGlkKTsKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJCS8qIFdlIHNob3VsZCBmb3JjZSB0aGUgd2lkZ2V0IHRvIHJlY2FsY3VsYXRlIGl0J3MKCQkgKiBnZW9tZXRyeSBub3cuICovCgkJWHRNYW5hZ2VDaGlsZChpZCk7CgkgICAgfQoJICAgIGVsc2UKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJICAgIFhtRm9udExpc3RGcmVlKGZsKTsKCX0KICAgIH0KI2Vsc2UKICAgIGlmIChndWkubWVudV9mb250ICE9IE5PRk9OVCkKICAgIHsKCVhtRm9udExpc3QgZmw7CgoJZmwgPSBndWlfbW90aWZfY3JlYXRlX2ZvbnRsaXN0KChYRm9udFN0cnVjdCAqKWd1aS5tZW51X2ZvbnQpOwoJaWYgKGZsICE9IE5VTEwpCgl7CgkgICAgaWYgKFh0SXNNYW5hZ2VkKGlkKSkKCSAgICB7CgkJWHRVbm1hbmFnZUNoaWxkKGlkKTsKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJCS8qIFdlIHNob3VsZCBmb3JjZSB0aGUgd2lkZ2V0IHRvIHJlY2FsY3VsYXRlIGl0J3MKCQkgKiBnZW9tZXRyeSBub3cuICovCgkJWHRNYW5hZ2VDaGlsZChpZCk7CgkgICAgfQoJICAgIGVsc2UKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJICAgIFhtRm9udExpc3RGcmVlKGZsKTsKCX0KICAgIH0KI2VuZGlmCiNlbmRpZgp9CgoKLyoKICogV2UgZG9uJ3QgY3JlYXRlIGl0IHR3aWNlIGZvciB0aGUgc2FrZSBvZiBzcGVlZC4KICovCgp0eXBlZGVmIHN0cnVjdCBfU2hhcmVkRmluZFJlcGxhY2UKewogICAgV2lkZ2V0IGRpYWxvZzsJLyogdGhlIG1haW4gZGlhbG9nIHdpZGdldCAqLwogICAgV2lkZ2V0IHd3b3JkOwkvKiAnRXhhY3QgbWF0Y2gnIGNoZWNrIGJ1dHRvbiAqLwogICAgV2lkZ2V0IG1jYXNlOwkvKiAnbWF0Y2ggY2FzZScgY2hlY2sgYnV0dG9uICovCiAgICBXaWRnZXQgdXA7CQkvKiBzZWFyY2ggZGlyZWN0aW9uICdVcCcgcmFkaW8gYnV0dG9uICovCiAgICBXaWRnZXQgZG93bjsJLyogc2VhcmNoIGRpcmVjdGlvbiAnRG93bicgcmFkaW8gYnV0dG9uICovCiAgICBXaWRnZXQgd2hhdDsJLyogJ0ZpbmQgd2hhdCcgZW50cnkgdGV4dCB3aWRnZXQgKi8KICAgIFdpZGdldCB3aXRoOwkvKiAnUmVwbGFjZSB3aXRoJyBlbnRyeSB0ZXh0IHdpZGdldCAqLwogICAgV2lkZ2V0IGZpbmQ7CS8qICdGaW5kIE5leHQnIGFjdGlvbiBidXR0b24gKi8KICAgIFdpZGdldCByZXBsYWNlOwkvKiAnUmVwbGFjZSBXaXRoJyBhY3Rpb24gYnV0dG9uICovCiAgICBXaWRnZXQgYWxsOwkJLyogJ1JlcGxhY2UgQWxsJyBhY3Rpb24gYnV0dG9uICovCiAgICBXaWRnZXQgdW5kbzsJLyogJ1VuZG8nIGFjdGlvbiBidXR0b24gKi8KCiAgICBXaWRnZXQgY2FuY2VsOwp9IFNoYXJlZEZpbmRSZXBsYWNlOwoKc3RhdGljIFNoYXJlZEZpbmRSZXBsYWNlIGZpbmRfd2lkZ2V0cyA9IHsgTlVMTCB9OwpzdGF0aWMgU2hhcmVkRmluZFJlcGxhY2UgcmVwbF93aWRnZXRzID0geyBOVUxMIH07CgpzdGF0aWMgdm9pZCBmaW5kX3JlcGxhY2VfZGVzdHJveV9jYWxsYmFjayBfX0FSR1MoKFdpZGdldCB3LCBYdFBvaW50ZXIgY2xpZW50X2RhdGEsIFh0UG9pbnRlciBjYWxsX2RhdGEpKTsKc3RhdGljIHZvaWQgZmluZF9yZXBsYWNlX2Rpc21pc3NfY2FsbGJhY2sgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYdFBvaW50ZXIgY2FsbF9kYXRhKSk7CnN0YXRpYyB2b2lkIGVudHJ5X2FjdGl2YXRlX2NhbGxiYWNrIF9fQVJHUygoV2lkZ2V0IHcsIFh0UG9pbnRlciBjbGllbnRfZGF0YSwgWHRQb2ludGVyIGNhbGxfZGF0YSkpOwpzdGF0aWMgdm9pZCBmaW5kX3JlcGxhY2VfY2FsbGJhY2sgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYdFBvaW50ZXIgY2FsbF9kYXRhKSk7CnN0YXRpYyB2b2lkIGZpbmRfcmVwbGFjZV9rZXlwcmVzcyBfX0FSR1MoKFdpZGdldCB3LCBTaGFyZWRGaW5kUmVwbGFjZSAqIGZyZHAsIFhLZXlFdmVudCAqIGV2ZW50KSk7CnN0YXRpYyB2b2lkIGZpbmRfcmVwbGFjZV9kaWFsb2dfY3JlYXRlIF9fQVJHUygoY2hhcl91ICplbnRyeV90ZXh0LCBpbnQgZG9fcmVwbGFjZSkpOwoKLypBUkdTVVNFRCovCiAgICBzdGF0aWMgdm9pZApmaW5kX3JlcGxhY2VfZGVzdHJveV9jYWxsYmFjayh3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXc7CiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGE7CiAgICBYdFBvaW50ZXIJY2FsbF9kYXRhOwp7CiAgICBTaGFyZWRGaW5kUmVwbGFjZSAqY2QgPSAoU2hhcmVkRmluZFJlcGxhY2UgKiljbGllbnRfZGF0YTsKCiAgICBpZiAoY2QgIT0gTlVMTCkKICAgICAgIC8qIHN1cHByZXNzX2RpYWxvZ19tbmVtb25pY3MoY2QtPmRpYWxvZyk7ICovCgljZC0+ZGlhbG9nID0gKFdpZGdldCkwOwp9CgovKkFSR1NVU0VEKi8KICAgIHN0YXRpYyB2b2lkCmZpbmRfcmVwbGFjZV9kaXNtaXNzX2NhbGxiYWNrKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdzsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsKICAgIFh0UG9pbnRlcgljYWxsX2RhdGE7CnsKICAgIFNoYXJlZEZpbmRSZXBsYWNlICpjZCA9IChTaGFyZWRGaW5kUmVwbGFjZSAqKWNsaWVudF9kYXRhOwoKICAgIGlmIChjZCAhPSBOVUxMKQoJWHRVbm1hbmFnZUNoaWxkKGNkLT5kaWFsb2cpOwp9CgovKkFSR1NVU0VEKi8KICAgIHN0YXRpYyB2b2lkCmVudHJ5X2FjdGl2YXRlX2NhbGxiYWNrKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdzsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsKICAgIFh0UG9pbnRlcgljYWxsX2RhdGE7CnsKICAgIFhtUHJvY2Vzc1RyYXZlcnNhbCgoV2lkZ2V0KWNsaWVudF9kYXRhLCBYbVRSQVZFUlNFX0NVUlJFTlQpOwp9CgovKkFSR1NVU0VEKi8KICAgIHN0YXRpYyB2b2lkCmZpbmRfcmVwbGFjZV9jYWxsYmFjayh3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXc7CiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGE7CiAgICBYdFBvaW50ZXIJY2FsbF9kYXRhOwp7CiAgICBsb25nX3UJZmxhZ3MgPSAobG9uZ191KWNsaWVudF9kYXRhOwogICAgY2hhcgkqZmluZF90ZXh0LCAqcmVwbF90ZXh0OwogICAgQm9vbGVhbglkaXJlY3Rpb25fZG93biA9IFRSVUU7CiAgICBCb29sZWFuCXd3b3JkOwogICAgQm9vbGVhbgltY2FzZTsKICAgIFNoYXJlZEZpbmRSZXBsYWNlICpzZnI7CgogICAgaWYgKGZsYWdzID09IEZSRF9VTkRPKQogICAgewoJY2hhcl91CSpzYXZlX2NwbyA9IHBfY3BvOwoKCS8qIE5vIG5lZWQgdG8gYmUgVmkgY29tcGF0aWJsZSBoZXJlLiAqLwoJcF9jcG8gPSAoY2hhcl91ICopIiI7Cgl1X3VuZG8oMSk7CglwX2NwbyA9IHNhdmVfY3BvOwoJZ3VpX3VwZGF0ZV9zY3JlZW4oKTsKCXJldHVybjsKICAgIH0KCiAgICAvKiBHZXQgdGhlIHNlYXJjaC9yZXBsYWNlIHN0cmluZ3MgZnJvbSB0aGUgZGlhbG9nICovCiAgICBpZiAoZmxhZ3MgPT0gRlJEX0ZJTkRORVhUKQogICAgewoJcmVwbF90ZXh0ID0gTlVMTDsKCXNmciA9ICZmaW5kX3dpZGdldHM7CiAgICB9CiAgICBlbHNlCiAgICB7CglyZXBsX3RleHQgPSBYbVRleHRGaWVsZEdldFN0cmluZyhyZXBsX3dpZGdldHMud2l0aCk7CglzZnIgPSAmcmVwbF93aWRnZXRzOwogICAgfQogICAgZmluZF90ZXh0ID0gWG1UZXh0RmllbGRHZXRTdHJpbmcoc2ZyLT53aGF0KTsKICAgIFh0VmFHZXRWYWx1ZXMoc2ZyLT5kb3duLCBYbU5zZXQsICZkaXJlY3Rpb25fZG93biwgTlVMTCk7CiAgICBYdFZhR2V0VmFsdWVzKHNmci0+d3dvcmQsIFhtTnNldCwgJnd3b3JkLCBOVUxMKTsKICAgIFh0VmFHZXRWYWx1ZXMoc2ZyLT5tY2FzZSwgWG1Oc2V0LCAmbWNhc2UsIE5VTEwpOwogICAgaWYgKHd3b3JkKQoJZmxhZ3MgfD0gRlJEX1dIT0xFX1dPUkQ7CiAgICBpZiAobWNhc2UpCglmbGFncyB8PSBGUkRfTUFUQ0hfQ0FTRTsKCiAgICAodm9pZClndWlfZG9fZmluZHJlcGwoKGludClmbGFncywgKGNoYXJfdSAqKWZpbmRfdGV4dCwgKGNoYXJfdSAqKXJlcGxfdGV4dCwKCQkJCQkJCSAgICAgIGRpcmVjdGlvbl9kb3duKTsKCiAgICBpZiAoZmluZF90ZXh0ICE9IE5VTEwpCglYdEZyZWUoZmluZF90ZXh0KTsKICAgIGlmIChyZXBsX3RleHQgIT0gTlVMTCkKCVh0RnJlZShyZXBsX3RleHQpOwp9CgovKkFSR1NVU0VEKi8KICAgIHN0YXRpYyB2b2lkCmZpbmRfcmVwbGFjZV9rZXlwcmVzcyh3LCBmcmRwLCBldmVudCkKICAgIFdpZGdldAkJdzsKICAgIFNoYXJlZEZpbmRSZXBsYWNlCSpmcmRwOwogICAgWEtleUV2ZW50CQkqZXZlbnQ7CnsKICAgIEtleVN5bSBrZXlzeW07CgogICAgaWYgKGZyZHAgPT0gTlVMTCkKCXJldHVybjsKCiAgICBrZXlzeW0gPSBYTG9va3VwS2V5c3ltKGV2ZW50LCAwKTsKCiAgICAvKiB0aGUgc2NhcGUga2V5IHBvcHMgdGhlIHdob2xlIGRpYWxvZyBkb3duICovCiAgICBpZiAoa2V5c3ltID09IFhLX0VzY2FwZSkKCVh0VW5tYW5hZ2VDaGlsZChmcmRwLT5kaWFsb2cpOwp9CgogICAgc3RhdGljIHZvaWQKc2V0X2xhYmVsKHcsIGxhYmVsKQogICAgV2lkZ2V0IHc7CiAgICBjaGFyX3UgKmxhYmVsOwp7CiAgICBYbVN0cmluZwlzdHI7CiAgICBjaGFyX3UJKnAsICpuZXh0OwogICAgS2V5U3ltCW1uZW1vbmljID0gTlVMOwoKICAgIGlmICghdykKCXJldHVybjsKCiAgICBwID0gdmltX3N0cnNhdmUobGFiZWwpOwogICAgaWYgKHAgPT0gTlVMTCkKCXJldHVybjsKICAgIGZvciAobmV4dCA9IHA7ICpuZXh0OyArK25leHQpCiAgICB7CglpZiAoKm5leHQgPT0gRExHX0hPVEtFWV9DSEFSKQoJewoJICAgIGludCBsZW4gPSBTVFJMRU4obmV4dCk7CgoJICAgIGlmIChsZW4gPiAwKQoJICAgIHsKCQltY2hfbWVtbW92ZShuZXh0LCBuZXh0ICsgMSwgbGVuKTsKCQltbmVtb25pYyA9IG5leHRbMF07CgkgICAgfQoJfQogICAgfQoKICAgIHN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKChjaGFyICopcCk7CiAgICB2aW1fZnJlZShwKTsKICAgIGlmIChzdHIpCiAgICB7CglYdFZhU2V0VmFsdWVzKHcsCgkJWG1ObGFiZWxTdHJpbmcsIHN0ciwKCQlYbU5tbmVtb25pYywgbW5lbW9uaWMsCgkJTlVMTCk7CglYbVN0cmluZ0ZyZWUoc3RyKTsKICAgIH0KICAgIGd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KHcpOwp9CgogICAgc3RhdGljIHZvaWQKZmluZF9yZXBsYWNlX2RpYWxvZ19jcmVhdGUoYXJnLCBkb19yZXBsYWNlKQogICAgY2hhcl91CSphcmc7CiAgICBpbnQJCWRvX3JlcGxhY2U7CnsKICAgIFNoYXJlZEZpbmRSZXBsYWNlCSpmcmRwOwogICAgV2lkZ2V0CQlzZXBhcmF0b3I7CiAgICBXaWRnZXQJCWlucHV0X2Zvcm07CiAgICBXaWRnZXQJCWJ1dHRvbl9mb3JtOwogICAgV2lkZ2V0CQl0b2dnbGVfZm9ybTsKICAgIFdpZGdldAkJZnJhbWU7CiAgICBYbVN0cmluZwkJc3RyOwogICAgaW50CQkJbjsKICAgIEFyZwkJCWFyZ3NbNl07CiAgICBpbnQJCQl3d29yZCA9IEZBTFNFOwogICAgaW50CQkJbWNhc2UgPSAhcF9pYzsKICAgIERpbWVuc2lvbgkJd2lkdGg7CiAgICBEaW1lbnNpb24JCXdpZGVzdDsKICAgIGNoYXJfdQkJKmVudHJ5X3RleHQ7CgogICAgZnJkcCA9IGRvX3JlcGxhY2UgPyAmcmVwbF93aWRnZXRzIDogJmZpbmRfd2lkZ2V0czsKCiAgICAvKiBHZXQgdGhlIHNlYXJjaCBzdHJpbmcgdG8gdXNlLiAqLwogICAgZW50cnlfdGV4dCA9IGdldF9maW5kX2RpYWxvZ190ZXh0KGFyZywgJnd3b3JkLCAmbWNhc2UpOwoKICAgIC8qIElmIHRoZSBkaWFsb2cgYWxyZWFkeSBleGlzdHMsIGp1c3QgcmFpc2UgaXQuICovCiAgICBpZiAoZnJkcC0+ZGlhbG9nKQogICAgewoJZ3VpX21vdGlmX3N5bmNoX2ZvbnRzKCk7CgoJLyogSWYgdGhlIHdpbmRvdyBpcyBhbHJlYWR5IHVwLCBqdXN0IHBvcCBpdCB0byB0aGUgdG9wICovCglpZiAoWHRJc01hbmFnZWQoZnJkcC0+ZGlhbG9nKSkKCSAgICBYTWFwUmFpc2VkKFh0RGlzcGxheShmcmRwLT5kaWFsb2cpLAoJCQkJCSAgICBYdFdpbmRvdyhYdFBhcmVudChmcmRwLT5kaWFsb2cpKSk7CgllbHNlCgkgICAgWHRNYW5hZ2VDaGlsZChmcmRwLT5kaWFsb2cpOwoJWHRQb3B1cChYdFBhcmVudChmcmRwLT5kaWFsb2cpLCBYdEdyYWJOb25lKTsKCVhtUHJvY2Vzc1RyYXZlcnNhbChmcmRwLT53aGF0LCBYbVRSQVZFUlNFX0NVUlJFTlQpOwoKCWlmIChlbnRyeV90ZXh0ICE9IE5VTEwpCgkgICAgWG1UZXh0RmllbGRTZXRTdHJpbmcoZnJkcC0+d2hhdCwgKGNoYXIgKillbnRyeV90ZXh0KTsKCXZpbV9mcmVlKGVudHJ5X3RleHQpOwoKCVh0VmFTZXRWYWx1ZXMoZnJkcC0+d3dvcmQsIFhtTnNldCwgd3dvcmQsIE5VTEwpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIENyZWF0ZSBhIGZyZXNoIG5ldyBkaWFsb2cgd2luZG93ICovCiAgICBpZiAoZG9fcmVwbGFjZSkKCSBzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZShfKCJWSU0gLSBTZWFyY2ggYW5kIFJlcGxhY2UuLi4iKSk7CiAgICBlbHNlCgkgc3RyID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoXygiVklNIC0gU2VhcmNoLi4uIikpOwoKICAgIG4gPSAwOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYXV0b1VubWFuYWdlLCBGYWxzZSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm5vUmVzaXplLCBUcnVlKTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OZGlhbG9nVGl0bGUsIHN0cik7IG4rKzsKCiAgICBmcmRwLT5kaWFsb2cgPSBYbUNyZWF0ZUZvcm1EaWFsb2codmltU2hlbGwsICJmaW5kUmVwbGFjZURpYWxvZyIsIGFyZ3MsIG4pOwogICAgWG1TdHJpbmdGcmVlKHN0cik7CiAgICBYdEFkZENhbGxiYWNrKGZyZHAtPmRpYWxvZywgWG1OZGVzdHJveUNhbGxiYWNrLAoJICAgIGZpbmRfcmVwbGFjZV9kZXN0cm95X2NhbGxiYWNrLCBmcmRwKTsKCiAgICBidXR0b25fZm9ybSA9IFh0VmFDcmVhdGVXaWRnZXQoImJ1dHRvbkZvcm0iLAoJICAgIHhtRm9ybVdpZGdldENsYXNzLAlmcmRwLT5kaWFsb2csCgkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTnJpZ2h0T2Zmc2V0LCA0LAoJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OdG9wT2Zmc2V0LCA0LAoJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OYm90dG9tT2Zmc2V0LCA0LAoJICAgIE5VTEwpOwoKICAgIGZyZHAtPmZpbmQgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgiZmluZEJ1dHRvbiIsCgkgICAgeG1QdXNoQnV0dG9uV2lkZ2V0Q2xhc3MsIGJ1dHRvbl9mb3JtLAoJICAgIFhtTnNlbnNpdGl2ZSwgVHJ1ZSwKCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBOVUxMKTsKICAgIHNldF9sYWJlbChmcmRwLT5maW5kLCBfKCJGaW5kICZOZXh0IikpOwoKICAgIFh0QWRkQ2FsbGJhY2soZnJkcC0+ZmluZCwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCSAgICBmaW5kX3JlcGxhY2VfY2FsbGJhY2ssCgkgICAgKFh0UG9pbnRlcikgKGRvX3JlcGxhY2UgPyBGUkRfUl9GSU5ETkVYVCA6IEZSRF9GSU5ETkVYVCkpOwoKICAgIGlmIChkb19yZXBsYWNlKQogICAgewoJZnJkcC0+cmVwbGFjZSA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJyZXBsYWNlQnV0dG9uIiwKCQl4bVB1c2hCdXR0b25XaWRnZXRDbGFzcywgYnV0dG9uX2Zvcm0sCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCVhtTnRvcFdpZGdldCwgZnJkcC0+ZmluZCwKCQlYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJTlVMTCk7CglzZXRfbGFiZWwoZnJkcC0+cmVwbGFjZSwgXygiJlJlcGxhY2UiKSk7CglYdEFkZENhbGxiYWNrKGZyZHAtPnJlcGxhY2UsIFhtTmFjdGl2YXRlQ2FsbGJhY2ssCgkJZmluZF9yZXBsYWNlX2NhbGxiYWNrLCAoWHRQb2ludGVyKUZSRF9SRVBMQUNFKTsKCglmcmRwLT5hbGwgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgicmVwbGFjZUFsbEJ1dHRvbiIsCgkJeG1QdXNoQnV0dG9uV2lkZ2V0Q2xhc3MsIGJ1dHRvbl9mb3JtLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU50b3BXaWRnZXQsIGZyZHAtPnJlcGxhY2UsCgkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCU5VTEwpOwoJc2V0X2xhYmVsKGZyZHAtPmFsbCwgXygiUmVwbGFjZSAmQWxsIikpOwoJWHRBZGRDYWxsYmFjayhmcmRwLT5hbGwsIFhtTmFjdGl2YXRlQ2FsbGJhY2ssCgkJZmluZF9yZXBsYWNlX2NhbGxiYWNrLCAoWHRQb2ludGVyKUZSRF9SRVBMQUNFQUxMKTsKCglmcmRwLT51bmRvID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInVuZG9CdXR0b24iLAoJCXhtUHVzaEJ1dHRvbldpZGdldENsYXNzLCBidXR0b25fZm9ybSwKCQlYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJWG1OdG9wV2lkZ2V0LCBmcmRwLT5hbGwsCgkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCU5VTEwpOwoJc2V0X2xhYmVsKGZyZHAtPnVuZG8sIF8oIiZVbmRvIikpOwoJWHRBZGRDYWxsYmFjayhmcmRwLT51bmRvLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCWZpbmRfcmVwbGFjZV9jYWxsYmFjaywgKFh0UG9pbnRlcilGUkRfVU5ETyk7CiAgICB9CgogICAgZnJkcC0+Y2FuY2VsID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoImNsb3NlQnV0dG9uIiwKCSAgICB4bVB1c2hCdXR0b25XaWRnZXRDbGFzcywgYnV0dG9uX2Zvcm0sCgkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgTlVMTCk7CiAgICBzZXRfbGFiZWwoZnJkcC0+Y2FuY2VsLCBfKCImQ2FuY2VsIikpOwogICAgWHRBZGRDYWxsYmFjayhmcmRwLT5jYW5jZWwsIFhtTmFjdGl2YXRlQ2FsbGJhY2ssCgkgICAgZmluZF9yZXBsYWNlX2Rpc21pc3NfY2FsbGJhY2ssIGZyZHApOwogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoZnJkcC0+Y2FuY2VsKTsKCiAgICBYdE1hbmFnZUNoaWxkKGJ1dHRvbl9mb3JtKTsKCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm9yaWVudGF0aW9uLCBYbVZFUlRJQ0FMKTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodFdpZGdldCwgYnV0dG9uX2Zvcm0pOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodE9mZnNldCwgNCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwogICAgc2VwYXJhdG9yID0gWG1DcmVhdGVTZXBhcmF0b3JHYWRnZXQoZnJkcC0+ZGlhbG9nLCAic2VwYXJhdG9yIiwgYXJncywgbik7CiAgICBYdE1hbmFnZUNoaWxkKHNlcGFyYXRvcik7CgogICAgaW5wdXRfZm9ybSA9IFh0VmFDcmVhdGVXaWRnZXQoImlucHV0Rm9ybSIsCgkgICAgeG1Gb3JtV2lkZ2V0Q2xhc3MsCWZyZHAtPmRpYWxvZywKCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU5sZWZ0T2Zmc2V0LCA0LAoJICAgIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJICAgIFhtTnJpZ2h0V2lkZ2V0LCBzZXBhcmF0b3IsCgkgICAgWG1OcmlnaHRPZmZzZXQsIDQsCgkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU50b3BPZmZzZXQsIDQsCgkgICAgTlVMTCk7CgogICAgewoJV2lkZ2V0IGxhYmVsX3doYXQ7CglXaWRnZXQgbGFiZWxfd2l0aCA9IChXaWRnZXQpMDsKCglzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZShfKCJGaW5kIHdoYXQ6IikpOwoJbGFiZWxfd2hhdCA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJ3aGF0TGFiZWwiLAoJCXhtTGFiZWxHYWRnZXRDbGFzcywgaW5wdXRfZm9ybSwKCQlYbU5sYWJlbFN0cmluZywgc3RyLAoJCVhtTmxlZnRBdHRhY2htZW50LAlYbUFUVEFDSF9GT1JNLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1OdG9wT2Zmc2V0LCA0LAoJCU5VTEwpOwoJWG1TdHJpbmdGcmVlKHN0cik7CglndWlfbW90aWZfbWVudV9mb250bGlzdChsYWJlbF93aGF0KTsKCglmcmRwLT53aGF0ID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoIndoYXRUZXh0IiwKCQl4bVRleHRGaWVsZFdpZGdldENsYXNzLCBpbnB1dF9mb3JtLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCU5VTEwpOwoKCWlmIChkb19yZXBsYWNlKQoJewoJICAgIGZyZHAtPndpdGggPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgid2l0aFRleHQiLAoJCSAgICB4bVRleHRGaWVsZFdpZGdldENsYXNzLAlpbnB1dF9mb3JtLAoJCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJICAgIFhtTnRvcFdpZGdldCwgZnJkcC0+d2hhdCwKCQkgICAgWG1OdG9wT2Zmc2V0LCA0LAoJCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCSAgICBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCSAgICBOVUxMKTsKCgkgICAgWHRBZGRDYWxsYmFjayhmcmRwLT53aXRoLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCSAgICBmaW5kX3JlcGxhY2VfY2FsbGJhY2ssIChYdFBvaW50ZXIpIEZSRF9SX0ZJTkRORVhUKTsKCgkgICAgc3RyID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoXygiUmVwbGFjZSB3aXRoOiIpKTsKCSAgICBsYWJlbF93aXRoID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoIndpdGhMYWJlbCIsCgkJICAgIHhtTGFiZWxHYWRnZXRDbGFzcywgaW5wdXRfZm9ybSwKCQkgICAgWG1ObGFiZWxTdHJpbmcsIHN0ciwKCQkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkgICAgWG1OdG9wV2lkZ2V0LCBmcmRwLT53aGF0LAoJCSAgICBYbU50b3BPZmZzZXQsIDQsCgkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIE5VTEwpOwoJICAgIFhtU3RyaW5nRnJlZShzdHIpOwoJICAgIGd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KGxhYmVsX3dpdGgpOwoKCSAgICAvKgoJICAgICAqIE1ha2UgdGhlIGVudHJ5IGFjdGl2YXRpb24gb25seSBjaGFuZ2UgdGhlIGlucHV0IGZvY3VzIG9udG8gdGhlCgkgICAgICogd2l0aCBpdGVtLgoJICAgICAqLwoJICAgIFh0QWRkQ2FsbGJhY2soZnJkcC0+d2hhdCwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCQkgICAgZW50cnlfYWN0aXZhdGVfY2FsbGJhY2ssIGZyZHAtPndpdGgpOwoJICAgIFh0QWRkRXZlbnRIYW5kbGVyKGZyZHAtPndpdGgsIEtleVByZXNzTWFzaywgRmFsc2UsCgkJCSAgICAoWHRFdmVudEhhbmRsZXIpZmluZF9yZXBsYWNlX2tleXByZXNzLAoJCQkgICAgKFh0UG9pbnRlcikgZnJkcCk7CgoJfQoJZWxzZQoJewoJICAgIC8qCgkgICAgICogTWFrZSB0aGUgZW50cnkgYWN0aXZhdGlvbiBkbyB0aGUgc2VhcmNoLgoJICAgICAqLwoJICAgIFh0QWRkQ2FsbGJhY2soZnJkcC0+d2hhdCwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCQkgICAgZmluZF9yZXBsYWNlX2NhbGxiYWNrLCAoWHRQb2ludGVyKUZSRF9GSU5ETkVYVCk7Cgl9CglYdEFkZEV2ZW50SGFuZGxlcihmcmRwLT53aGF0LCBLZXlQcmVzc01hc2ssIEZhbHNlLAoJCQkgICAgKFh0RXZlbnRIYW5kbGVyKWZpbmRfcmVwbGFjZV9rZXlwcmVzcywKCQkJICAgIChYdFBvaW50ZXIpZnJkcCk7CgoJLyogR2V0IHRoZSBtYXhpbXVtIHdpZHRoIGJldHdlZW4gdGhlIGxhYmVsIHdpZGdldHMgYW5kIGxpbmUgdGhlbSB1cC4KCSAqLwoJbiA9IDA7CglYdFNldEFyZyhhcmdzW25dLCBYbU53aWR0aCwgJndpZHRoKTsgbisrOwoJWHRHZXRWYWx1ZXMobGFiZWxfd2hhdCwgYXJncywgbik7Cgl3aWRlc3QgPSB3aWR0aDsKCWlmIChkb19yZXBsYWNlKQoJewoJICAgIFh0R2V0VmFsdWVzKGxhYmVsX3dpdGgsIGFyZ3MsIG4pOwoJICAgIGlmICh3aWR0aCA+IHdpZGVzdCkKCQl3aWRlc3QgPSB3aWR0aDsKCX0KCglYdFZhU2V0VmFsdWVzKGZyZHAtPndoYXQsIFhtTmxlZnRPZmZzZXQsIHdpZGVzdCwgTlVMTCk7CglpZiAoZG9fcmVwbGFjZSkKCSAgICBYdFZhU2V0VmFsdWVzKGZyZHAtPndpdGgsIFhtTmxlZnRPZmZzZXQsIHdpZGVzdCwgTlVMTCk7CgogICAgfQoKICAgIFh0TWFuYWdlQ2hpbGQoaW5wdXRfZm9ybSk7CgogICAgewoJV2lkZ2V0IHJhZGlvX2JveDsKCVdpZGdldCB3OwoKCWZyYW1lID0gWHRWYUNyZWF0ZVdpZGdldCgiZGlyZWN0aW9uRnJhbWUiLAoJCXhtRnJhbWVXaWRnZXRDbGFzcywgZnJkcC0+ZGlhbG9nLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU50b3BXaWRnZXQsIGlucHV0X2Zvcm0sCgkJWG1OdG9wT2Zmc2V0LCA0LAoJCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1OYm90dG9tT2Zmc2V0LCA0LAoJCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfT1BQT1NJVEVfV0lER0VULAoJCVhtTnJpZ2h0V2lkZ2V0LCBpbnB1dF9mb3JtLAoJCU5VTEwpOwoKCXN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKF8oIkRpcmVjdGlvbiIpKTsKCXcgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgiZGlyZWN0aW9uRnJhbWVMYWJlbCIsCgkJeG1MYWJlbEdhZGdldENsYXNzLCBmcmFtZSwKCQlYbU5sYWJlbFN0cmluZywgc3RyLAoJCVhtTmNoaWxkSG9yaXpvbnRhbEFsaWdubWVudCwgWG1BTElHTk1FTlRfQkVHSU5OSU5HLAoJCVhtTmNoaWxkVHlwZSwgWG1GUkFNRV9USVRMRV9DSElMRCwKCQlOVUxMKTsKCVhtU3RyaW5nRnJlZShzdHIpOwoJZ3VpX21vdGlmX21lbnVfZm9udGxpc3Qodyk7CgoJcmFkaW9fYm94ID0gWG1DcmVhdGVSYWRpb0JveChmcmFtZSwgInJhZGlvQm94IiwKCQkoQXJnTGlzdClOVUxMLCAwKTsKCglzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZSggXygiVXAiKSk7CglmcmRwLT51cCA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJ1cFJhZGlvQnV0dG9uIiwKCQl4bVRvZ2dsZUJ1dHRvbkdhZGdldENsYXNzLCByYWRpb19ib3gsCgkJWG1ObGFiZWxTdHJpbmcsIHN0ciwKCQlYbU5zZXQsIEZhbHNlLAoJCU5VTEwpOwoJWG1TdHJpbmdGcmVlKHN0cik7CglndWlfbW90aWZfbWVudV9mb250bGlzdChmcmRwLT51cCk7CgoJc3RyID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoXygiRG93biIpKTsKCWZyZHAtPmRvd24gPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgiZG93blJhZGlvQnV0dG9uIiwKCQl4bVRvZ2dsZUJ1dHRvbkdhZGdldENsYXNzLCByYWRpb19ib3gsCgkJWG1ObGFiZWxTdHJpbmcsIHN0ciwKCQlYbU5zZXQsIFRydWUsCgkJTlVMTCk7CglYbVN0cmluZ0ZyZWUoc3RyKTsKCWd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KGZyZHAtPmRvd24pOwoKCVh0TWFuYWdlQ2hpbGQocmFkaW9fYm94KTsKCVh0TWFuYWdlQ2hpbGQoZnJhbWUpOwogICAgfQoKICAgIHRvZ2dsZV9mb3JtID0gWHRWYUNyZWF0ZVdpZGdldCgidG9nZ2xlRm9ybSIsCgkgICAgeG1Gb3JtV2lkZ2V0Q2xhc3MsCWZyZHAtPmRpYWxvZywKCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU5sZWZ0T2Zmc2V0LCA0LAoJICAgIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJICAgIFhtTnJpZ2h0V2lkZ2V0LCBmcmFtZSwKCSAgICBYbU5yaWdodE9mZnNldCwgNCwKCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkgICAgWG1OdG9wV2lkZ2V0LCBpbnB1dF9mb3JtLAoJICAgIFhtTnRvcE9mZnNldCwgNCwKCSAgICBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmJvdHRvbU9mZnNldCwgNCwKCSAgICBOVUxMKTsKCiAgICBzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZShfKCJNYXRjaCB3aG9sZSB3b3JkIG9ubHkiKSk7CiAgICBmcmRwLT53d29yZCA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJ3b3JkVG9nZ2xlIiwKCSAgICB4bVRvZ2dsZUJ1dHRvbkdhZGdldENsYXNzLCB0b2dnbGVfZm9ybSwKCSAgICBYbU5sYWJlbFN0cmluZywgc3RyLAoJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OdG9wT2Zmc2V0LCA0LAoJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmxlZnRPZmZzZXQsIDQsCgkgICAgWG1Oc2V0LCB3d29yZCwKCSAgICBOVUxMKTsKICAgIFhtU3RyaW5nRnJlZShzdHIpOwoKICAgIHN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKF8oIk1hdGNoIGNhc2UiKSk7CiAgICBmcmRwLT5tY2FzZSA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJjYXNlVG9nZ2xlIiwKCSAgICB4bVRvZ2dsZUJ1dHRvbkdhZGdldENsYXNzLCB0b2dnbGVfZm9ybSwKCSAgICBYbU5sYWJlbFN0cmluZywgc3RyLAoJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmxlZnRPZmZzZXQsIDQsCgkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJICAgIFhtTnRvcFdpZGdldCwgZnJkcC0+d3dvcmQsCgkgICAgWG1OdG9wT2Zmc2V0LCA0LAoJICAgIFhtTnNldCwgbWNhc2UsCgkgICAgTlVMTCk7CiAgICBYbVN0cmluZ0ZyZWUoc3RyKTsKICAgIGd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KGZyZHAtPnd3b3JkKTsKICAgIGd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KGZyZHAtPm1jYXNlKTsKCiAgICBYdE1hbmFnZUNoaWxkKHRvZ2dsZV9mb3JtKTsKCiAgICBpZiAoZW50cnlfdGV4dCAhPSBOVUxMKQoJWG1UZXh0RmllbGRTZXRTdHJpbmcoZnJkcC0+d2hhdCwgKGNoYXIgKillbnRyeV90ZXh0KTsKICAgIHZpbV9mcmVlKGVudHJ5X3RleHQpOwoKICAgIGd1aV9tb3RpZl9zeW5jaF9mb250cygpOwoKICAgIG1hbmFnZV9jZW50ZXJlZChmcmRwLT5kaWFsb2cpOwogICAgYWN0aXZhdGVfZGlhbG9nX21uZW1vbmljcyhmcmRwLT5kaWFsb2cpOwogICAgWG1Qcm9jZXNzVHJhdmVyc2FsKGZyZHAtPndoYXQsIFhtVFJBVkVSU0VfQ1VSUkVOVCk7Cn0KCiAgIHZvaWQKZ3VpX21jaF9maW5kX2RpYWxvZyhlYXApCiAgICBleGFyZ19UCSplYXA7CnsKICAgIGlmICghZ3VpLmluX3VzZSkKCXJldHVybjsKCiAgICBmaW5kX3JlcGxhY2VfZGlhbG9nX2NyZWF0ZShlYXAtPmFyZywgRkFMU0UpOwp9CgoKICAgIHZvaWQKZ3VpX21jaF9yZXBsYWNlX2RpYWxvZyhlYXApCiAgICBleGFyZ19UCSplYXA7CnsKICAgIGlmICghZ3VpLmluX3VzZSkKCXJldHVybjsKCiAgICBmaW5kX3JlcGxhY2VfZGlhbG9nX2NyZWF0ZShlYXAtPmFyZywgVFJVRSk7Cn0KCi8qCiAqIFN5bmNocm9uaXplIGFsbCBndWkgZWxlbWVudHMsIHdoaWNoIGFyZSBkZXBlbmRhbnQgdXBvbiB0aGUKICogbWFpbiB0ZXh0IGZvbnQgdXNlZC4gVGhvc2UgYXJlIGluIGVzcC4gdGhlIGZpbmQvcmVwbGFjZSBkaWFsb2dzLgogKiBJZiB5b3UgZG9uJ3QgdW5kZXJzdGFuZCB3aHkgdGhpcyBzaG91bGQgYmUgbmVlZGVkLCBwbGVhc2UgdHJ5IHRvCiAqIHNlYXJjaCBmb3IgInBp6rbmIiBpbiBpc284ODU5LTIuCiAqLwogICAgdm9pZApndWlfbW90aWZfc3luY2hfZm9udHModm9pZCkKewogICAgU2hhcmVkRmluZFJlcGxhY2UgKmZyZHA7CiAgICBpbnQJCSAgICBkb19yZXBsYWNlOwogICAgWEZvbnRTdHJ1Y3QJICAgICpmb250OwogICAgWG1Gb250TGlzdAkgICAgZm9udF9saXN0OwoKICAgIC8qIEZJWE1FOiBVbmxlc3Mgd2UgZmluZCBvdXQgaG93IHRvIGNyZWF0ZSBhIFhtRm9udExpc3QgZnJvbSBhIFhGb250U2V0LAogICAgICogd2UganVzdCBnaXZlIHVwIGhlcmUgb24gZm9udCBzeW5jaHJvbml6YXRpb24uICovCiAgICBmb250ID0gKFhGb250U3RydWN0ICopZ3VpLm5vcm1fZm9udDsKICAgIGlmIChmb250ID09IE5VTEwpCglyZXR1cm47CgogICAgZm9udF9saXN0ID0gZ3VpX21vdGlmX2NyZWF0ZV9mb250bGlzdChmb250KTsKCiAgICAvKiBPSyB0aGlzIGxvb3AgaXMgYSBiaXQgdHJpY2t5Li4uICovCiAgICBmb3IgKGRvX3JlcGxhY2UgPSAwOyBkb19yZXBsYWNlIDw9IDE7ICsrZG9fcmVwbGFjZSkKICAgIHsKCWZyZHAgPSAoZG9fcmVwbGFjZSkgPyAoJnJlcGxfd2lkZ2V0cykgOiAoJmZpbmRfd2lkZ2V0cyk7CglpZiAoZnJkcC0+ZGlhbG9nKQoJewoJICAgIFh0VmFTZXRWYWx1ZXMoZnJkcC0+d2hhdCwgWG1OZm9udExpc3QsIGZvbnRfbGlzdCwgTlVMTCk7CgkgICAgaWYgKGRvX3JlcGxhY2UpCgkJWHRWYVNldFZhbHVlcyhmcmRwLT53aXRoLCBYbU5mb250TGlzdCwgZm9udF9saXN0LCBOVUxMKTsKCX0KICAgIH0KCiAgICBYbUZvbnRMaXN0RnJlZShmb250X2xpc3QpOwp9Cg==