LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiAyNy5yZWFkc29tZS5jcHAgLSB0ZXN0IGV4ZXJjaXNpbmcgaXN0cmVhbTo6cmVhZHNvbWUoKQogKgogKiAkSWQkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSAgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQogKiBjb250cmlidXRvciAgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlICB0aGUgTk9USUNFICBmaWxlIGRpc3RyaWJ1dGVkCiAqIHdpdGggIHRoaXMgIHdvcmsgIGZvciAgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiAgcmVnYXJkaW5nICBjb3B5cmlnaHQKICogb3duZXJzaGlwLiAgIFRoZSBBU0YgIGxpY2Vuc2VzIHRoaXMgIGZpbGUgdG8gIHlvdSB1bmRlciAgdGhlIEFwYWNoZQogKiBMaWNlbnNlLCBWZXJzaW9uICAyLjAgKHRoZSAgIkxpY2Vuc2UiKTsgeW91IG1heSAgbm90IHVzZSAgdGhpcyBmaWxlCiAqIGV4Y2VwdCBpbiAgY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAgIFlvdSBtYXkgb2J0YWluICBhIGNvcHkgb2YKICogdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlICBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUICBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgIE9GIEFOWSAgS0lORCwgZWl0aGVyICBleHByZXNzIG9yCiAqIGltcGxpZWQuICAgU2VlICB0aGUgTGljZW5zZSAgZm9yICB0aGUgIHNwZWNpZmljIGxhbmd1YWdlICBnb3Zlcm5pbmcKICogcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKgogKiBDb3B5cmlnaHQgMjAwMy0yMDA3IFJvZ3VlIFdhdmUgU29mdHdhcmUuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSA8aXN0cmVhbT4KI2luY2x1ZGUgPHNzdHJlYW0+CgojaW5jbHVkZSA8cndfZHJpdmVyLmg+CiNpbmNsdWRlIDxyd19jaGFyLmg+ICAgICAvLyBmb3IgVXNlckNoYXIsIFVzZXJUcmFpdHMKI2luY2x1ZGUgPHJ3X3ByaW50Zi5oPiAgIC8vIGZvciByd19wcmludGYoKQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdGVtcGxhdGUgPGNsYXNzIGNoYXJULCBjbGFzcyBUcmFpdHM+CnN0cnVjdCBTdHJlYW1idWY6IHN0ZDo6YmFzaWNfc3RyZWFtYnVmPGNoYXJULCBUcmFpdHM+CnsKICAgIHR5cGVkZWYgc3RkOjpiYXNpY19zdHJlYW1idWY8Y2hhclQsIFRyYWl0cz4gQmFzZTsKICAgIHR5cGVkZWYgdHlwZW5hbWUgQmFzZTo6dHJhaXRzX3R5cGUgICAgICAgICAgdHJhaXRzX3R5cGU7CiAgICB0eXBlZGVmIHR5cGVuYW1lIEJhc2U6OmludF90eXBlICAgICAgICAgICAgIGludF90eXBlOwoKICAgIC8vIHZhbHVlIHJldHVybmVkIGZyb20gc2hvd21hbnljKCkKICAgIGludCBzaG93bWFueWNfOwoKICAgIC8vIHVuZGVyZmxvdygpIHdpbGwgcmV0dXJuIGVvZiAoKSBhZnRlciBleHRyYWN0aW5nIHRoaXMgbWFueSBjaGFycwogICAgaW50IGZhaWxfYWZ0ZXJfOwoKICAgIC8vIHVuZGVyZmxvdygpIHdpbGwgdGhyb3cgYW0gZXhjZXB0aW9uIGFmdGVyIGV4dHJhY3RpbmcgdGhpcyBtYW55IGNoYXJzCiAgICBpbnQgdGhyb3dfYWZ0ZXJfOwoKICAgIGNvbnN0IGNoYXJUICplbmRfOyAgICAgICAgICAvLyB0aGUgZW5kIG9mIHRoZSBidWZmZXIgKGZ1dHVyZSBlYmFjaygpKQoKICAgIFN0cmVhbWJ1ZiAoY29uc3QgY2hhclQgKmdiZWcsIGNvbnN0IGNoYXJUICpnZW5kKQogICAgICAgIDogQmFzZSAoKSwKICAgICAgICAgIHNob3dtYW55Y18gKDApLAogICAgICAgICAgZmFpbF9hZnRlcl8gKC0xKSwgICAgLy8gbmV2ZXIgZmFpbAogICAgICAgICAgdGhyb3dfYWZ0ZXJfICgtMSksICAgLy8gbmV2ZXIgdGhyb3cKICAgICAgICAgIGVuZF8gKGdlbmQpIHsKICAgICAgICB0aGlzLT5zZXRnIChfUldTVERfQ09OU1RfQ0FTVCAoY2hhclQqLCBnYmVnKSwKICAgICAgICAgICAgICAgICAgICBfUldTVERfQ09OU1RfQ0FTVCAoY2hhclQqLCBnYmVnKSwKICAgICAgICAgICAgICAgICAgICBfUldTVERfQ09OU1RfQ0FTVCAoY2hhclQqLCBnYmVnKSk7CiAgICB9CgogICAgY29uc3QgY2hhclQqIHB1YmViYWNrICgpIGNvbnN0IHsKICAgICAgICByZXR1cm4gdGhpcy0+ZWJhY2sgKCk7CiAgICB9CgogICAgY29uc3QgY2hhclQqIHB1YmdwdHIgKCkgY29uc3QgewogICAgICAgIHJldHVybiB0aGlzLT5ncHRyICgpOwogICAgfQoKICAgIGNvbnN0IGNoYXJUKiBwdWJlZ3B0ciAoKSBjb25zdCB7CiAgICAgICAgcmV0dXJuIHRoaXMtPmVncHRyICgpOwogICAgfQoKICAgIC8qIHZpcnR1YWwgKi8gc3RkOjpzdHJlYW1zaXplIHNob3dtYW55YyAoKSB7CiNpZm5kZWYgX1JXU1REX05PX0VYQ0VQVElPTlMKCiAgICAgICAgaWYgKC0yID09IHNob3dtYW55Y18pCiAgICAgICAgICAgIHRocm93IChjb25zdCBjaGFyKikic2hvd21hbnljIjsKCiNlbmRpZiAgIC8vIF9SV1NURF9OT19FWENFUFRJT05TCgogICAgICAgIHJldHVybiBzaG93bWFueWNfOwogICAgfQoKICAgIC8qIHZpcnR1YWwgKi8gaW50X3R5cGUgdW5kZXJmbG93ICgpIHsKICAgICAgICBpZiAodGhpcy0+Z3B0ciAoKSA9PSBlbmRfKQogICAgICAgICAgICByZXR1cm4gdHJhaXRzX3R5cGU6OmVvZiAoKTsKCiAgICAgICAgaWYgKHRocm93X2FmdGVyXyA9PSB0aGlzLT5ncHRyICgpIC0gdGhpcy0+ZWJhY2sgKCkpIHsKCiNpZm5kZWYgX1JXU1REX05PX0VYQ0VQVElPTlMKCiAgICAgICAgICAgIHRocm93IChjb25zdCBjaGFyKikidW5kZXJmbG93IjsKCiNlbHNlICAgLy8gaWYgZGVmaW5lZCAoX1JXU1REX05PX0VYQ0VQVElPTlMpCgogICAgICAgICAgICByZXR1cm4gdHJhaXRzX3R5cGU6OmVvZiAoKTsKCiNlbmRpZiAgIC8vIF9SV1NURF9OT19FWENFUFRJT05TCgogICAgICAgIH0KCiAgICAgICAgaWYgKGZhaWxfYWZ0ZXJfID09IHRoaXMtPmdwdHIgKCkgLSB0aGlzLT5lYmFjayAoKSkKICAgICAgICAgICAgcmV0dXJuIHRyYWl0c190eXBlOjplb2YgKCk7CgogICAgICAgIHRoaXMtPnNldGcgKHRoaXMtPmViYWNrICgpLCB0aGlzLT5ncHRyICgpLCB0aGlzLT5ncHRyICgpICsgMSk7CiAgICAgICAgcmV0dXJuIHRyYWl0c190eXBlOjp0b19pbnRfdHlwZSAoKnRoaXMtPmdwdHIgKCkpOwogICAgfQp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgMjcuNi4xLjMsIHAzMCBhbmQgMzEKCiAgICBzdHJlYW1zaXplIHJlYWRzb21lIChjaGFyX3R5cGUqIHMsIHN0cmVhbXNpemUgbik7CgogICAgLTMwLSBFZmZlY3RzOiBJZiAhZ29vZCgpIGNhbGxzIHNldHN0YXRlKGZhaWxiaXQpIHdoaWNoIG1heSB0aHJvdyBhbgogICAgICAgICBleGNlcHRpb24sIGFuZCByZXR1cm4uIE90aGVyd2lzZSBleHRyYWN0cyBjaGFyYWN0ZXJzIGFuZCBzdG9yZXMKICAgICAgICAgdGhlbSBpbnRvIHN1Y2Nlc3NpdmUgbG9jYXRpb25zIG9mIGFuIGFycmF5IHdob3NlIGZpcnN0IGVsZW1lbnQKICAgICAgICAgaXMgZGVzaWduYXRlZCBieSBzLgogICAgICAgICAtLSAgSWYgcmRidWYoKa0+aW5fYXZhaWwoKSA9PSCtMSwgY2FsbHMgc2V0c3RhdGUoZW9mYml0KSAod2hpY2gKICAgICAgICAgICAgIG1heSB0aHJvdyBpb3NfYmFzZTo6ZmFpbHVyZSAoMjcuNC40LjMpKSwgYW5kIGV4dHJhY3RzIG5vCiAgICAgICAgICAgICBjaGFyYWN0ZXJzOwogICAgICAgICAtLSAgSWYgcmRidWYoKa0+aW5fYXZhaWwoKSA9PSAwLCBleHRyYWN0cyBubyBjaGFyYWN0ZXJzCiAgICAgICAgIC0tICBJZiByZGJ1ZigprT5pbl9hdmFpbCgpID4gMCwgZXh0cmFjdHMgbWluKHJkYnVmKCmtPmluX2F2YWlsKCksCiAgICAgICAgICAgICBuKSkuCiAgICAtMzEtIFJldHVybnM6IFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBleHRyYWN0ZWQuCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp2b2lkCm1lbWZ1bl9pbmZvIChpbnQgbGluZSwgY29uc3QgY2hhciAqY25hbWUsIGNvbnN0IGNoYXIgKnRuYW1lKQp7CiAgICAvLyBmb3JtYXQgdGhlIElTVFJFQU0gZW52aXJvbm1lbnQgdmFyaWFibGUgdy9vIHdyaXRpbmcKICAgIC8vIG91dCBhbnkgb3V0cHV0CiAgICByd19mcHJpbnRmICgwLAogICAgICAgICAgICAgICAgIiV7JElTVFJFQU0hOkB9IiwKICAgICAgICAgICAgICAgICIlez99aXN0cmVhbSV7On0lez99d2lzdHJlYW0iCiAgICAgICAgICAgICAgICAiJXs6fWJhc2ljX2lzdHJlYW08JXMsICVzPiV7O30lezt9IiwKICAgICAgICAgICAgICAgICdjJyA9PSAqY25hbWUgJiYgJ2MnID09ICp0bmFtZSwgCiAgICAgICAgICAgICAgICAndycgPT0gKmNuYW1lICYmICdjJyA9PSAqdG5hbWUsCiAgICAgICAgICAgICAgICBjbmFtZSwgdG5hbWUpOwoKICAgIHJ3X2luZm8gKDAsIDAsIGxpbmUsCiAgICAgICAgICAgICAic3RkOjoleyRJU1RSRUFNfTo6cmVhZHNvbWUgKGNoYXJfdHlwZSosIHN0cmVhbXNpemUpIik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpleHRlcm4gY29uc3Qgc3RkOjppb3NfYmFzZTo6aW9zdGF0ZQpzdGF0ZXNbXSA9IHsKICAgIHN0ZDo6aW9zX2Jhc2U6OmJhZGJpdCwKICAgIHN0ZDo6aW9zX2Jhc2U6OmVvZmJpdCwKICAgIHN0ZDo6aW9zX2Jhc2U6OmZhaWxiaXQsCiAgICBzdGQ6Omlvc19iYXNlOjpnb29kYml0LAogICAgc3RkOjppb3NfYmFzZTo6YmFkYml0IHwgc3RkOjppb3NfYmFzZTo6ZW9mYml0LAogICAgc3RkOjppb3NfYmFzZTo6YmFkYml0IHwgc3RkOjppb3NfYmFzZTo6ZmFpbGJpdCwKICAgIHN0ZDo6aW9zX2Jhc2U6OmVvZmJpdCB8IHN0ZDo6aW9zX2Jhc2U6OmZhaWxiaXQsCiAgICBzdGQ6Omlvc19iYXNlOjpiYWRiaXQgfCBzdGQ6Omlvc19iYXNlOjplb2ZiaXQgfCBzdGQ6Omlvc19iYXNlOjpmYWlsYml0Cn07CgpleHRlcm4gY29uc3QgdW5zaWduZWQgbnN0YXRlcyA9IHNpemVvZiBzdGF0ZXMgLyBzaXplb2YgKnN0YXRlczsKCgp0ZW1wbGF0ZSA8Y2xhc3MgY2hhclQsIGNsYXNzIFRyYWl0cz4Kdm9pZCB0ZXN0X3JlYWRzb21lIChjb25zdCBjaGFyVCAqY2J1ZiwgY29uc3QgVHJhaXRzKiwKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjYnVmX3NpemUsCiAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaSwgICAvLyBpbmRleCBpbnRvIHN0YXRlcwogICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGosICAgLy8gbnVtYmVyIG9mIGNoYXJzIHRvIHJlYWQKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBrLCAgIC8vIHdoZW4gdW5kZXJmbG93KCkgd2lsbCBmYWlsCiAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgbCwgICAvLyB2YWx1ZSByZXR1cm5lZCBmcm9tIHNob3dtYW55YygpCiAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbSkgICAvLyBob3cgdW5kZXJmbG93IHNob3VsZCBmYWlsKCkKewogICAgdHlwZWRlZiBzdGQ6OmJhc2ljX2lzdHJlYW08Y2hhclQsIFRyYWl0cz4gSXN0cmVhbTsKCiAgICBzdGF0aWMgdW5zaWduZWQgaXRlciA9IDA7ICAgLy8gaXRlcmF0aW9uIGNvdW50ZXIKCiAgICAvLyBjb25zdHJ1Y3QgYSBzdHJlYW0gYnVmZmVyIG9iamVjdCBhbmQgaW5pdGlhbGl6ZSBpdHMgcmVhZAogICAgLy8gc2VxdWVuY2Ugd2l0aCB0aGUgY2hhcmFjdGVyIGJ1ZmZlcgogICAgU3RyZWFtYnVmPGNoYXJULCBUcmFpdHM+IHNiIChjYnVmLCBjYnVmICsgY2J1Zl9zaXplIC0gMSk7CgogICAgc2Iuc2hvd21hbnljXyA9IGw7CgogICAgY29uc3QgY2hhciogZXJyX3R5cGUgPSAwOwoKICAgIGlmIChtIDwgMSkgewogICAgICAgIC8vIGhhdmUgdGhlIHN0cmVhbSBidWZmZXIgb2JqZWN0J3MgdW5kZXJmbG93KCkgZmFpbCAoYnkKICAgICAgICAvLyB0aHJvd2luZyBhbiBleGNlcHRpb24gaWYgcG9zc2libGUpIGFmdGVyIGsgY2hhcmFjdGVycwogICAgICAgIC8vIGhhdmUgYmVlbiBleHRyYWN0ZWQgKHRoaXMgb2JqZWN0IGNhbGxzIHVuZGVyZmxvdygpIGZvcgogICAgICAgIC8vIGV2ZXJ5IGNoYXIpCiAgICAgICAgc2IudGhyb3dfYWZ0ZXJfID0gazsKICAgICAgICBlcnJfdHlwZSAgICAgICAgPSAidGhyZXciOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgLy8gaGF2ZSB0aGUgc3RyZWFtIGJ1ZmZlciBvYmplY3QncyB1bmRlcmZsb3coKSBmYWlsIGJ5CiAgICAgICAgLy8gcmV0dXJuaW5nIGVvZiBhZnRlciBrIGNoYXJhY3RlcnMgaGF2ZSBiZWVuIGV4dHJhY3RlZAogICAgICAgIC8vICh0aGlzIG9iamVjdCBjYWxscyB1bmRlcmZsb3coKSBmb3IgZXZlcnkgY2hhcikKICAgICAgICBzYi5mYWlsX2FmdGVyXyA9IGs7CiAgICAgICAgZXJyX3R5cGUgICAgICAgPSAicmV0dXJuZWQgRU9GIjsKICAgIH0KCiAgICAvLyBjb25zdHJ1Y3QgYW4gaXN0cmVhbSBvYmplY3QgYW5kIGluaXRpYWxpemUgaXQgd2l0aCB0aGUgdXNlcgogICAgLy8gZGVmaW5lZCBzdHJlYW1idWYgb2JqZWN0CiAgICBJc3RyZWFtIGlzICgmc2IpOwoKICAgIC8vIHNldCB0aGUgc3RyZWFtIG9iamVjdCdzIGluaXRpYWwgc3RhdGUKICAgIGlzLnNldHN0YXRlIChzdGF0ZXMgW2ldKTsKCiAgICAvLyB0aGUgbnVtYmVyIG9mIGV4dHJhY3RlZCB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMgZXhwZWN0ZWQgdG8KICAgIC8vIGJlIHJlcG9ydGVkIGJ5IGdjb3VudCgpIG11c3QgZXF1YWwgdGhlIG51bWJlciBvZiBzdWNjZXNzZnVsCiAgICAvLyBleHRyYWN0aW9ucyBjb21wdXRlZCBieSB0aGUgdGhlIHN0cmVhbSBidWZmZXIgb3ZlcnJpZGRlbgogICAgLy8gdW5kZXJmbG93IG1lbWJlciBmdW5jdGlvbgogICAgY29uc3QgaW50IGV4dHJhY3QgPQogICAgICAgIGlzLmdvb2QgKCkgPyBqIDwgayA/IGludCAoaikgPCBsID8gagogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbCA8IDAgPyAwIDogbAogICAgICAgICAgICAgICAgICAgICAgICAgICA6IGludCAoaykgPCBsID8gawogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbCA8IDAgPyAwIDogbAogICAgICAgICAgICAgICAgICAgOiAwOwoKICAgIGNoYXJUIGJ1ZiBbMjU2XSA9IHsgMCB9OwoKICAgIHN0ZDo6c3RyZWFtc2l6ZSBucmVhZCA9IC0xOwoKICAgIC8vIGZvcm1hdCB0aGUgRkNBTEwgZW52aXJvbm1lbnQgdmFyaWFibGUgc28gdGhhdCBpdCBjYW4gYmUKICAgIC8vIGNvbnZlbmllbnRseSB1c2VkIGluIGRpYWdub3N0aWNzIGJlbG93CiAgICByd19mcHJpbnRmICgwLCAiJXUuICV7JEZDQUxMITpAfSIsCiAgICAgICAgICAgICAgICBpdGVyLAogICAgICAgICAgICAgICAgIiV7JElTVFJFQU19KCV7KkFjfSkucmVhZHNvbWUoJXAsICVkKSIsCiAgICAgICAgICAgICAgICBpbnQgKHNpemVvZiAqY2J1ZiksIGNidWYsIGJ1Ziwgaik7CgojaWZuZGVmIF9SV1NURF9OT19FWENFUFRJT05TCgogICAgY29uc3QgY2hhciAqY2F1Z2h0ID0gMDsKCiAgICAvLyBvbiBldmVyeSBvdGhlciBpdGVyYXRpb24gc2V0IGJhZGJpdCBpbiBleGNlcHRpb25zIHRvIGNoZWNrCiAgICAvLyB0aGF0IHRoZSB0aHJvd24gb2JqZWN0IGlzIHByb3BhZ2F0ZWQgYnkgdGhlIGZ1bmN0aW9uCiAgICBpZiAoayAlIDIgJiYgIWlzLmJhZCAoKSkKICAgICAgICBpcy5leGNlcHRpb25zIChzdGQ6Omlvc19iYXNlOjpiYWRiaXQpOwoKICAgIHRyeSB7CiAgICAgICAgbnJlYWQgPSBpcy5yZWFkc29tZSAoYnVmLCBqKTsKICAgIH0KICAgIGNhdGNoIChjb25zdCBjaGFyICpzKSB7CiAgICAgICAgY2F1Z2h0ID0gczsKICAgIH0KICAgIGNhdGNoICguLi4pIHsKCiAgICAgICAgY2F1Z2h0ID0gIi4uLiI7CgogICAgICAgIHJ3X2Fzc2VydCAoMCwgMCwgX19MSU5FX18sCiAgICAgICAgICAgICAgICAgICAiJXskRkNBTEx9IHRocmV3IGFuIGV4Y2VwdGlvbiBvZiB1bmV4cGVjdGVkIHR5cGUiKTsKICAgIH0KCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgIC8vIHZlcmlmeSB0aGF0IHRoZSBmdW5jdGlvbiBwcm9wYWdhdGVzIGV4Y2VwdGlvbnMgdGhyb3duIGZyb20gdGhlCiAgICAvLyBzdHJlYW1idWYgb2JqZWN0IG9ubHkgd2hlbiBiYWRiaXQgaXMgc2V0IGluIHRoZSBzdHJlYW0gb2JqZWN0J3MKICAgIC8vIGV4Y2VwdGlvbnMoKQoKICAgIHJ3X2Fzc2VydCAoIWNhdWdodCB8fCAoayAlIDIpLCAwLCBfX0xJTkVfXywKICAgICAgICAgICAgICAgIiV7JEZDQUxMfSB1bmV4cGVjdGVkbHkgcHJvcGFnYXRlZCBhbiBleGNlcHRpb24iKTsKCiNlbHNlICAgLy8gaWYgZGVmaW5lZCAoX1JXU1REX05PX0VYQ0VQVElPTlMpCgogICAgbnJlYWQgPSBpcy5yZWFkc29tZSAoYnVmLCBqKTsKCiNlbmRpZiAgIC8vIF9SV1NURF9OT19FWENFUFRJT05TCgogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvLyB2ZXJpZnkgdGhhdCB0aGUgZnVuY3Rpb24gcmV0dXJuZWQgdGhlIGV4cGVjdGVkIG51bWJlciBvZgogICAgLy8gZXh0cmFjdGVkIGNoYXJhY3RlcnMKCiAgICBjb25zdCBzdGQ6OnN0cmVhbXNpemUgZXh0cmFjdGVkID0gc2IucHViZ3B0ciAoKSAtIHNiLnB1YmViYWNrICgpOwoKICAgIHJ3X2Fzc2VydCAoZXh0cmFjdCA9PSBleHRyYWN0ZWQsIDAsIF9fTElORV9fLAogICAgICAgICAgICAgICAiJXskRkNBTEx9IGV4cGVjdGVkIHRvIGV4dHJhY3QgJWQgY2hhcnMsIGdvdCAldTsgIgogICAgICAgICAgICAgICAiaW5pdGlhbCBzdGF0ZSA9ICV7SXN9LCB1bmRlcmZsb3cgJXMgYXQgZXh0cmFjdGlvbiAldSIsCiAgICAgICAgICAgICAgIGV4dHJhY3QsIGV4dHJhY3RlZCwgc3RhdGVzIFtpXSwKICAgICAgICAgICAgICAgZXJyX3R5cGUsIGspOwoKICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgLy8gdmVyaWZ5IHRoYXQgdGhlIGV4cGVjdGVkIG51bWJlciBvZiBjaGFyYWN0ZXJzIGhhdmUgYmVlbgogICAgLy8gZXh0cmFjdGVkIGZyb20gdGhlIHN0cmVhbQoKICAgIHJ3X2Fzc2VydCAoY2J1ZiArIGV4dHJhY3QgPT0gc2IucHViZ3B0ciAoKSwgMCwgX19MSU5FX18sCiAgICAgICAgICAgICAgICIleyRGQ0FMTH0gZXhwZWN0ZWQgdG8gZXh0cmFjdCAlZCBjaGFycywgZ290ICV1OyAiCiAgICAgICAgICAgICAgICJpbml0aWFsIHN0YXRlID0gJXtJc30sIHVuZGVyZmxvdyAlcyBhdCBleHRyYWN0aW9uICV1IiwKICAgICAgICAgICAgICAgZXh0cmFjdCwgZXh0cmFjdGVkLCBzdGF0ZXMgW2ldLAogICAgICAgICAgICAgICBlcnJfdHlwZSwgayk7CgogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvLyB2ZXJpZnkgdGhhdCB0aGUgZXh0cmFjdGVkIGNoYXJhY3RlcnMgbWF0Y2ggdGhvc2UgaW4gdGhlIGJ1ZmZlcgoKICAgIHJ3X2Fzc2VydCAoMCA9PSBzdGQ6OmNoYXJfdHJhaXRzPGNoYXJUPjo6Y29tcGFyZSAoYnVmLCBjYnVmLCBleHRyYWN0KSwKICAgICAgICAgICAgICAgMCwgX19MSU5FX18sCiAgICAgICAgICAgICAgICIleyRGQ0FMTH0gZXhwZWN0ZWQgdG8gZXh0cmFjdCB0aGUgZmlyc3QgJWQgY2hhcnMsIGdvdCAleypBY30iLAogICAgICAgICAgICAgICBleHRyYWN0LCBpbnQgKHNpemVvZiAqYnVmKSwgYnVmKTsKCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgIC8vIHZlcmlmeSB0aGF0IGdjb3VudCgpIGNvcnJlY3RseSByZWZsZWN0cyB0aGUgbnVtYmVyIG9mCiAgICAvLyBjaGFyYWN0ZXJzIHN1Y2Nlc3NmdWxseSBleHRyYWN0ZWQgZnJvbSB0aGUgc3RyZWFtCgogICAgcndfYXNzZXJ0IChleHRyYWN0ID09IGlzLmdjb3VudCAoKSwgMCwgX19MSU5FX18sCiAgICAgICAgICAgICAgICIleyRGQ0FMTH06IGdjb3VudCgpID09ICVkLCBnb3QgJWQ7IGluaXRpYWwgc3RhdGUgPSAle0lzfSwgIgogICAgICAgICAgICAgICAidW5kZXJmbG93ICVzIGF0IGV4dHJhY3Rpb24gJXUiLAogICAgICAgICAgICAgICBleHRyYWN0LCBpcy5nY291bnQgKCksIHN0YXRlcyBbaV0sCiAgICAgICAgICAgICAgIGVycl90eXBlLCBrKTsKCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgIC8vIHZlcmlmeSB0aGUgc3RhdGUgb2YgdGhlIHN0cmVhbSBvYmplY3QgYWZ0ZXIgdGhlIGZ1bmN0aW9uIGNhbGwKCiAgICAvLyBleHBlY3RlZCBzdHJlYW0gc3RhdGUgYWZ0ZXIgdGhlIGZ1bmN0aW9uIGNhbGwgaXMgdW5jaGFuZ2VkCiAgICAvLyAoaS5lLiwgdGhlIGluaXRpYWwgc3RyZWFtIHN0YXRlKSwgZXhjZXB0Li4uCiAgICBzdGQ6Omlvc19iYXNlOjppb3N0YXRlIGV4cGVjdF9zdGF0ZSA9IHN0YXRlcyBbaV07CgogICAgaWYgKCFzdGF0ZXMgW2ldKSB7CgojaWZuZGVmIF9SV1NURF9OT19FWENFUFRJT05TCgogICAgICAgIC8vIC4uLmlmIGFuIGV4dHJhY3Rpb24gaXMgYXR0ZW1wdGVkLCBvciBldmVuIGlmIHRoZSBmaXJzdAogICAgICAgIC8vIGNoYXJhY3RlciBvbiB0aGUgc3RyZWFtIGlzIHBlZWtlZCBhdCwgYW5kIGFuIGV4Y2VwdGlvbgogICAgICAgIC8vIGlzIHRocm93biBkdXJpbmcgaW5wdXQsIGJhZGJpdCBzaG91bGQgYmUgc2V0LCBvdGhlcndpc2UKICAgICAgICAvLyBpZiBpbl9hdmFpbCgpIHJldHVybmVkIC0xLCBlb2ZiaXQgc2hvdWxkIGJlIHNldCwgZWxzZQogICAgICAgIC8vIHRoZSBzdGF0ZSBzaG91bGQgYmUgZ29vZAogICAgICAgIGlmICgtMiA9PSBsKQogICAgICAgICAgICBleHBlY3Rfc3RhdGUgPSBzdGQ6Omlvc19iYXNlOjpiYWRiaXQ7CiAgICAgICAgZWxzZSBpZiAobCA8IDApCiAgICAgICAgICAgIGV4cGVjdF9zdGF0ZSA9IHN0ZDo6aW9zX2Jhc2U6OmVvZmJpdDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGV4cGVjdF9zdGF0ZSA9IHN0ZDo6aW9zX2Jhc2U6Omdvb2RiaXQ7CgojZWxzZSAgIC8vIGlmIGRlZmluZWQgKF9SV1NURF9OT19FWENFUFRJT05TKQoKICAgICAgICBpZiAobCA8IDApCiAgICAgICAgICAgIGV4cGVjdF9zdGF0ZSA9IHN0ZDo6aW9zX2Jhc2U6OmVvZmJpdDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGV4cGVjdF9zdGF0ZSA9IHN0ZDo6aW9zX2Jhc2U6Omdvb2RiaXQ7CgojZW5kaWYgICAvLyBfUldTVERfTk9fRVhDRVBUSU9OUwoKICAgIH0KICAgIGVsc2UgewoKICAgICAgICAvLyAuLi5pZiB0aGUgaW5pdGlhbCBzdHJlYW0gc3RhdGUgaXMgbm90IGdvb2QsIGZhaWxiaXQKICAgICAgICAvLyBtdXN0IGJlIHNldAogICAgICAgIGV4cGVjdF9zdGF0ZSA9IHN0YXRlcyBbaV0gfCBzdGQ6Omlvc19iYXNlOjpmYWlsYml0OwogICAgfQoKICAgIHJ3X2Fzc2VydCAoaXMucmRzdGF0ZSAoKSA9PSBleHBlY3Rfc3RhdGUsIDAsIF9fTElORV9fLAogICAgICAgICAgICAgICAiJXskRkNBTEx9OiByZHN0YXRlKCkgPT0gJXtJc30sIGdvdCAle0lzfTsgIgogICAgICAgICAgICAgICAiZXh0cmFjdGVkICV1IGNoYXJhY3RlcnM7ICIKICAgICAgICAgICAgICAgImluaXRpYWwgc3RhdGUgPSAle0lzfSwgdW5kZXJmbG93ICVzIGF0IGV4dHJhY3Rpb24gJXUiLAogICAgICAgICAgICAgICBleHBlY3Rfc3RhdGUsIGlzLnJkc3RhdGUgKCksIGV4dHJhY3RlZCwKICAgICAgICAgICAgICAgc3RhdGVzIFtpXSwgZXJyX3R5cGUsIGspOwoKICAgICsraXRlcjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCnRlbXBsYXRlIDxjbGFzcyBjaGFyVCwgY2xhc3MgVHJhaXRzPgp2b2lkIHRlc3RfcmVhZHNvbWUgKGNvbnN0IGNoYXJUKiwgY29uc3QgVHJhaXRzKiwKICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpjbmFtZSwgY29uc3QgY2hhciAqdG5hbWUpCnsKICAgIG1lbWZ1bl9pbmZvIChfX0xJTkVfXywgY25hbWUsIHRuYW1lKTsKCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgLy8gZXhlcmNpc2UgMjcuNi4xLjMsIHAxCgogICAgY29uc3QgY2hhclQgY2J1ZltdID0geyAnICcsICdhJywgJyAnLCAnYicsICdjJywgJ1wwJyB9OwogICAgY29uc3QgdW5zaWduZWQgY2J1Zl9zaXplID0gc2l6ZW9mIGNidWYgLyBzaXplb2YgKmNidWY7CgogICAgdW5zaWduZWQgaXRlciAgID0gMDsgICAvLyBpdGVyYXRpb24gY291bnRlcgoKICAgIC8vIGl0ZXJhdGUgb3ZlciBhbGwgcG9zc2libGUgc2V0dGluZ3Mgb2YgdGhlIHN0cmVhbSBzdGF0ZQogICAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSAhPSBuc3RhdGVzOyArK2kpIHsKCiAgICAgICAgLy8gY2FsbCByZWFkc29tZSguLi4sIGopIHRvIGV4dHJhY3QgaiBjaGFyYWN0ZXJzIAogICAgICAgIGZvciAodW5zaWduZWQgaiA9IDA7IGogIT0gY2J1Zl9zaXplIC0gMTsgKytqKSB7CgogICAgICAgICAgICAvLyBoYXZlIHVuZGVyZmxvdygpIGZhaWwgYWZ0ZXIgdGhlIGBrLXRoJyBleHRyYWN0aW9uCiAgICAgICAgICAgIGZvciAodW5zaWduZWQgayA9IDA7IGsgIT0gaiArIDE7ICsraykgewoKICAgICAgICAgICAgICAgIC8vIHJldHVybiBgbCcgZnJvbSBzaG93bWFueWMoKTsgLTIgd2lsbCB0aHJvdwogICAgICAgICAgICAgICAgZm9yIChpbnQgbCA9IC00OyBsICE9IGludCAoayk7ICsrbCkgewoKICAgICAgICAgICAgICAgICAgICAvLyBpZiAoMCA9PSBtKSwgdW5kZXJmbG93KCkgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24KICAgICAgICAgICAgICAgICAgICAvLyBhdCBgay10aCcgZXh0cmFjdGlvbiwgb3RoZXJ3aXNlIHRoZSBmdW5jdGlvbiB3aWxsCiAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJuIEVPRgogICAgICAgICAgICAgICAgICAgIGZvciAodW5zaWduZWQgbSA9IDA7IG0gIT0gMjsgKyttLCArK2l0ZXIpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByZXZlbnQgY2F1c2luZyB1bmRlcmZsb3coKSB0byBmYWlsIGJ5CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJldHVybmluZyBFT0Ygd2hlbiBpbl9hdmFpbCgpIHByb21pc2VkCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0IHdvdWxkbid0IChieSByZXR1cm5pbmcgYSB2YWx1ZQogICAgICAgICAgICAgICAgICAgICAgICAvLyBncmVhdGVyIHRoYW4gdGhlIG51bWJlciBvZiBleHRyYWN0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmRlcmZsb3coKSB3aWxsIGFsbG93IHRvIHN1Y2NlZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgxVSA9PSBtICYmIGludCAoaykgPCBsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAgICAgICAgICAgICB0ZXN0X3JlYWRzb21lIChjYnVmLCAoVHJhaXRzKikwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYnVmX3NpemUsIGksIGosIGssIGwsIG0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIGludCBvcHRfY2hhcjsKc3RhdGljIGludCBvcHRfd2NoYXI7CnN0YXRpYyBpbnQgb3B0X2NoYXJfdHJhaXRzOwpzdGF0aWMgaW50IG9wdF91c2VyX3RyYWl0czsKCgpzdGF0aWMgaW50CnJ1bl90ZXN0IChpbnQsIGNoYXIqKikKewogICAgLy8gaW50cm9kdWNlIGNoYXJfdHJhaXRzIGludG8gc2NvcGUKICAgIHVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojdW5kZWYgVEVTVAojZGVmaW5lIFRFU1QoQ2hhclQsIFRyYWl0cykgXAogICAgdGVzdF9yZWFkc29tZSAoKENoYXJUKikwLCAoVHJhaXRzKikwLCAjQ2hhclQsICNUcmFpdHMpCgogICAgaWYgKHJ3X25vdGUgKDAgPD0gb3B0X2NoYXIgJiYgMCA8PSBvcHRfY2hhcl90cmFpdHMsIDAsIF9fTElORV9fLAogICAgICAgICAgICAgICAgICJiYXNpY19pc3RyZWFtPGNoYXIsIGNoYXJfdHJhaXRzPGNoYXI+Pjo6cmVhZHNvbWUoKSAiCiAgICAgICAgICAgICAgICAgInRlc3RzIGRpc2FibGVkIikpCiAgICAgICAgVEVTVCAoY2hhciwgY2hhcl90cmFpdHM8Y2hhcj4pOwoKICAgIGlmIChyd19ub3RlICgwIDw9IG9wdF9jaGFyICYmIDAgPD0gb3B0X3VzZXJfdHJhaXRzLCAwLCBfX0xJTkVfXywKICAgICAgICAgICAgICAgICAiYmFzaWNfaXN0cmVhbTxjaGFyLCBVc2VyVHJhaXRzPGNoYXI+Pjo6cmVhZHNvbWUoKSAiCiAgICAgICAgICAgICAgICAgInRlc3RzIGRpc2FibGVkIikpCiAgICAgICAgVEVTVCAoY2hhciwgVXNlclRyYWl0czxjaGFyPik7CgojaWZuZGVmIF9SV1NURF9OT19XQ0hBUl9UCgogICAgaWYgKHJ3X25vdGUgKDAgPD0gb3B0X3djaGFyICYmIDAgPD0gb3B0X2NoYXJfdHJhaXRzLCAwLCBfX0xJTkVfXywKICAgICAgICAgICAgICAgICAiYmFzaWNfaXN0cmVhbTx3Y2hhcl90LCBjaGFyX3RyYWl0czx3Y2hhcl90Pj46OnJlYWRzb21lKCkgIgogICAgICAgICAgICAgICAgICJ0ZXN0cyBkaXNhYmxlZCIpKQogICAgICAgIFRFU1QgKHdjaGFyX3QsIGNoYXJfdHJhaXRzPHdjaGFyX3Q+KTsKCiAgICBpZiAocndfbm90ZSAoMCA8PSBvcHRfd2NoYXIgJiYgMCA8PSBvcHRfdXNlcl90cmFpdHMsIDAsIF9fTElORV9fLAogICAgICAgICAgICAgICAgICJiYXNpY19pc3RyZWFtPHdjaGFyX3QsIFVzZXJUcmFpdHM8d2NoYXJfdD4+OjpyZWFkc29tZSgpICIKICAgICAgICAgICAgICAgICAidGVzdHMgZGlzYWJsZWQiKSkKICAgICAgICBURVNUICh3Y2hhcl90LCBVc2VyVHJhaXRzPHdjaGFyX3Q+KTsKCiNlbmRpZiAgIC8vIF9SV1NURF9OT19XQ0hBUl9UCgogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCmludCBtYWluIChpbnQgYXJnYywgY2hhciAqYXJndltdKQp7CiAgICByZXR1cm4gcndfdGVzdCAoYXJnYywgYXJndiwgX19GSUxFX18sCiAgICAgICAgICAgICAgICAgICAgImlzdHJlYW0udW5mb3JtYXR0ZWQiLAogICAgICAgICAgICAgICAgICAgICJyZWFkc29tZSIsCiAgICAgICAgICAgICAgICAgICAgcnVuX3Rlc3QsCiAgICAgICAgICAgICAgICAgICAgInwtY2hhcn4gIgogICAgICAgICAgICAgICAgICAgICJ8LXdjaGFyX3R+ICIKICAgICAgICAgICAgICAgICAgICAifC1jaGFyX3RyYWl0c34gIgogICAgICAgICAgICAgICAgICAgICJ8LVVzZXJUcmFpdHN+ICIsCiAgICAgICAgICAgICAgICAgICAgJm9wdF9jaGFyLAogICAgICAgICAgICAgICAgICAgICZvcHRfd2NoYXIsCiAgICAgICAgICAgICAgICAgICAgJm9wdF9jaGFyX3RyYWl0cywKICAgICAgICAgICAgICAgICAgICAmb3B0X3VzZXJfdHJhaXRzLAogICAgICAgICAgICAgICAgICAgICh2b2lkKikwICAgLyogc2VudGluZWwgKi8pOwp9Cg==