LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBpc3RyZWFtX3NlbnRyeS5jcHAgLSB0ZXN0IGV4ZXJjaXNpbmcgYmFzaWNfaXN0cmVhbTxjaGFyVD46OnNlbnRyeQogKgogKiAkSWQkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSAgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQogKiBjb250cmlidXRvciAgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlICB0aGUgTk9USUNFICBmaWxlIGRpc3RyaWJ1dGVkCiAqIHdpdGggIHRoaXMgIHdvcmsgIGZvciAgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiAgcmVnYXJkaW5nICBjb3B5cmlnaHQKICogb3duZXJzaGlwLiAgIFRoZSBBU0YgIGxpY2Vuc2VzIHRoaXMgIGZpbGUgdG8gIHlvdSB1bmRlciAgdGhlIEFwYWNoZQogKiBMaWNlbnNlLCBWZXJzaW9uICAyLjAgKHRoZSAgIkxpY2Vuc2UiKTsgeW91IG1heSAgbm90IHVzZSAgdGhpcyBmaWxlCiAqIGV4Y2VwdCBpbiAgY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAgIFlvdSBtYXkgb2J0YWluICBhIGNvcHkgb2YKICogdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlICBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUICBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgIE9GIEFOWSAgS0lORCwgZWl0aGVyICBleHByZXNzIG9yCiAqIGltcGxpZWQuICAgU2VlICB0aGUgTGljZW5zZSAgZm9yICB0aGUgIHNwZWNpZmljIGxhbmd1YWdlICBnb3Zlcm5pbmcKICogcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKgogKiBDb3B5cmlnaHQgMjAwMy0yMDA2IFJvZ3VlIFdhdmUgU29mdHdhcmUuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSA8aXN0cmVhbT4KI2luY2x1ZGUgPGxvY2FsZT4gICAgICAgIC8vIGZvciBjdHlwZQojaW5jbHVkZSA8c3RyZWFtYnVmPiAgICAgLy8gZm9yIHN0cmVhbWJ1ZgoKI2luY2x1ZGUgPHJ3X2NoYXIuaD4gICAgIC8vIGZvciBVc2VyQ2hhciwgVXNlclRyYWl0cwojaW5jbHVkZSA8cndfcHJpbnRmLmg+ICAgLy8gZm9yIHJ3X3ByaW50ZigpCiNpbmNsdWRlIDxkcml2ZXIuaD4KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICAyNy42LjEuMS4yICAgQ2xhc3MgYmFzaWNfaXN0cmVhbTo6c2VudHJ5ICAgW2xpYi5pc3RyZWFtOjpzZW50cnldCgogICAgbmFtZXNwYWNlIHN0ZCB7CiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIGNoYXJULCBjbGFzcyB0cmFpdHMgPSBjaGFyX3RyYWl0czxjaGFyVD4gPgogICAgICAgIGNsYXNzIGJhc2ljX2lzdHJlYW08Y2hhclQsIHRyYWl0cz46OnNlbnRyeSB7CiAgICAgICAgICAgIHR5cGVkZWYgdHJhaXRzIHRyYWl0c190eXBlOwogICAgICAgICAgICBib29sIG9rXzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXhwb3NpdGlvbiBvbmx5CiAgICAgICAgcHVibGljOgogICAgICAgICAgICBleHBsaWNpdAogICAgICAgICAgICBzZW50cnkgKGJhc2ljX2lzdHJlYW08Y2hhclQsIHRyYWl0cz4mIGlzLCBib29sIG5vc2tpcHdzID0gZmFsc2UpOwogICAgICAgICAgICB+c2VudHJ5ICgpOwogICAgICAgICAgICBvcGVyYXRvciBib29sKCkgY29uc3QgeyByZXR1cm4gb2tfOyB9CiAgICAgICAgcHJpdmF0ZToKICAgICAgICAgICAgc2VudHJ5IChjb25zdCBzZW50cnkmKTsgICAgICAgICAgICAgIC8vIG5vdCBkZWZpbmVkCiAgICAgICAgICAgIHNlbnRyeSYgb3BlcmF0b3I9IChjb25zdCBzZW50cnkmKTsgICAvLyBub3QgZGVmaW5lZAogICAgICAgIH07CiAgICB9CgogICAgLTEtIFRoZSBjbGFzcyBzZW50cnkgZGVmaW5lcyBhIGNsYXNzIHRoYXQgaXMgcmVzcG9uc2libGUgZm9yIGRvaW5nCiAgICAgICAgZXhjZXB0aW9uIHNhZmUgcHJlZml4IGFuZCBzdWZmaXggb3BlcmF0aW9ucy4KCiAgICBleHBsaWNpdCBzZW50cnkoYmFzaWNfaXN0cmVhbTxjaGFyVCwgdHJhaXRzPiYgaXMsIGJvb2wgbm9za2lwd3MgPSBmYWxzZSk7CiAgICAtMi0gRWZmZWN0czogSWYgaXMuZ29vZCgpIGlzIHRydWUsIHByZXBhcmVzIGZvciBmb3JtYXR0ZWQgb3IgdW5mb3JtYXR0ZWQKICAgICAgICBpbnB1dC4gRmlyc3QsIGlmIGlzLnRpZSgpIGlzIG5vdCBhIG51bGwgcG9pbnRlciwgdGhlIGZ1bmN0aW9uIGNhbGxzCiAgICAgICAgaXMudGllKCmtPmZsdXNoKCkgdG8gc3luY2hyb25pemUgdGhlIG91dHB1dCBzZXF1ZW5jZSB3aXRoIGFueQogICAgICAgIGFzc29jaWF0ZWQgZXh0ZXJuYWwgQyBzdHJlYW0uIEV4Y2VwdCB0aGF0IHRoaXMgY2FsbCBjYW4gYmUgc3VwcHJlc3NlZAogICAgICAgIGlmIHRoZSBwdXQgYXJlYSBvZiBpcy50aWUoKSBpcyBlbXB0eS4gRnVydGhlciBhbiBpbXBsZW1lbnRhdGlvbiBpcwogICAgICAgIGFsbG93ZWQgdG8gZGVmZXIgdGhlIGNhbGwgdG8gZmx1c2ggdW50aWwgYSBjYWxsIG9mCiAgICAgICAgaXMtPnJkYnVmKCmtPnVuZGVyZmxvdyBvY2N1cnMuIElmIG5vIHN1Y2ggY2FsbCBvY2N1cnMgYmVmb3JlIHRoZQogICAgICAgIHNlbnRyeSBvYmplY3QgaXMgZGVzdHJveWVkLCB0aGUgY2FsbCB0byBmbHVzaCBtYXkgYmUgZWxpbWluYXRlZAogICAgICAgIGVudGlyZWx5KDI3OSkuIElmIG5vc2tpcHdzIGlzIHplcm8gYW5kIGlzLmZsYWdzKCkgJiBpb3NfYmFzZTo6c2tpcHdzCiAgICAgICAgaXMgbm9uemVybywgdGhlIGZ1bmN0aW9uIGV4dHJhY3RzIGFuZCBkaXNjYXJkcyBlYWNoIGNoYXJhY3RlciBhcyBsb25nCiAgICAgICAgYXMgdGhlIG5leHQgYXZhaWxhYmxlIGlucHV0IGNoYXJhY3RlciBjIGlzIGEgd2hpdGVzcGFjZSBjaGFyYWN0ZXIuCiAgICAtMy0gTm90ZXM6IFRoZSBjb25zdHJ1Y3RvciBleHBsaWNpdCBzZW50cnkoYmFzaWNfaXN0cmVhbTxjaGFyVCwgdHJhaXRzPiYKICAgICAgICBpcywgYm9vbCBub3NraXB3cyA9IGZhbHNlKSB1c2VzIHRoZSBjdXJyZW50bHkgaW1idWVkIGxvY2FsZSBpbiBpcywKICAgICAgICB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgbmV4dCBpbnB1dCBjaGFyYWN0ZXIgaXMgd2hpdGVzcGFjZSBvciBub3QuCiAgICAtNC0gVG8gZGVjaWRlIGlmIHRoZSBjaGFyYWN0ZXIgY2lzIGEgd2hpdGVzcGFjZSBjaGFyYWN0ZXIsIHRoZSBjb25zdHJ1Y3RvcgogICAgICAgIHBlcmZvcm1zICJhcyBpZiIgaXQgZXhlY3V0ZXMgdGhlIGZvbGxvd2luZyBjb2RlIGZyYWdtZW50OgogICAgICAgIGNvbnN0IGN0eXBlPGNoYXJUPiYgY3R5cGUgPSB1c2VfZmFjZXQ8Y3R5cGU8Y2hhclQ+ID4oaXMuZ2V0bG9jKCkpOwogICAgICAgIGlmIChjdHlwZS5pcyAoY3R5cGUuc3BhY2UsYykgIT0gMCkKICAgICAgICAgICAgLy8gYyBpcyBhIHdoaXRlc3BhY2UgY2hhcmFjdGVyLgogICAgLTUtIElmLCBhZnRlciBhbnkgcHJlcGFyYXRpb24gaXMgY29tcGxldGVkLCBpcy5nb29kKCkgaXMgdHJ1ZSwKICAgICAgICBva18gIT0gZmFsc2Ugb3RoZXJ3aXNlLCBva18gPT0gZmFsc2UuIER1cmluZyBwcmVwYXJhdGlvbiwgdGhlCiAgICAgICAgY29uc3RydWN0b3IgbWF5IGNhbGwgc2V0c3RhdGUoZmFpbGJpdCkgKHdoaWNoIG1heSB0aHJvdwogICAgICAgIGlvc19iYXNlOjpmYWlsdXJlICgyNy40LjQuMykpKDI4MCkKICAgIF9fX19fX19fX19fX19fX19fXwogICAgMjc5KSBUaGlzIHdpbGwgYmUgcG9zc2libGUgb25seSBpbiBmdW5jdGlvbnMgdGhhdCBhcmUgcGFydCBvZiB0aGUKICAgICAgICAgbGlicmFyeS4gVGhlIHNlbWFudGljcyBvZiB0aGUgY29uc3RydWN0b3IgdXNlZCBpbiB1c2VyIGNvZGUgaXMKICAgICAgICAgYXMgc3BlY2lmaWVkLgogICAgMjgwKSBUaGUgc2VudHJ5IGNvbnN0cnVjdG9yIGFuZCBkZXN0cnVjdG9yIGNhbiBhbHNvIHBlcmZvcm0gYWRkaXRpb25hbAogICAgICAgICBpbXBsZW1lbnRhdGlvbi1kZXBlbmRlbnQgb3BlcmF0aW9ucy4KCiAgICAtNi0gW0V4YW1wbGU6IEEgdHlwaWNhbCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgc2VudHJ5IGNvbnN0cnVjdG9yIG1pZ2h0CiAgICAgICAgaW5jbHVkZSBjb2RlIHN1Y2ggYXM6CgogICAgICAgIHRlbXBsYXRlIDxjbGFzcyBjaGFyVCwgY2xhc3MgdHJhaXRzID0gY2hhcl90cmFpdHM8Y2hhclQ+ID4KICAgICAgICBiYXNpY19pc3RyZWFtPGNoYXJULHRyYWl0cz46OnNlbnRyeSgKICAgICAgICAgICAgYmFzaWNfaXN0cmVhbTxjaGFyVCx0cmFpdHM+JiBpcywgYm9vbCBub3NraXB3cyA9IGZhbHNlKSB7CiAgICAgICAgICAgIC4uLgogICAgICAgICAgICBpbnRfdHlwZSBjOwogICAgICAgICAgICB0eXBlZGVmIGN0eXBlPGNoYXJUPiBjdHlwZV90eXBlOwogICAgICAgICAgICBjb25zdCBjdHlwZV90eXBlJiBjdHlwZSA9IHVzZV9mYWNldDxjdHlwZV90eXBlPihpcy5nZXRsb2MoKSk7CiAgICAgICAgICAgIHdoaWxlICgoYyA9IGlzLnJkYnVmKCmtPnNuZXh0YygpKSAhPSB0cmFpdHM6OmVvZigpKSB7CiAgICAgICAgICAgICAgICBpZiAoY3R5cGUuaXMoY3R5cGUuc3BhY2UsYyk9PTApIHsKICAgICAgICAgICAgICAgICAgICBpcy5yZGJ1ZigprT5zcHV0YmFja2MgKGMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC4uLgogICAgICAgIH0KICAgICAgICAtLWVuZCBleGFtcGxlXQoKICAgIH5zZW50cnkoKTsKICAgIC03LSBFZmZlY3RzOiBOb25lLgoKICAgIG9wZXJhdG9yIGJvb2woKSBjb25zdDsKICAgIC04LSBFZmZlY3RzOiBSZXR1cm5zIG9rXy4KCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnZvaWQKbWVtZnVuX2luZm8gKGludCBsaW5lLCBjb25zdCBjaGFyICpjbmFtZSwgY29uc3QgY2hhciAqdG5hbWUsIGNvbnN0IGNoYXIgKmZuYW1lKQp7CiAgICAvLyBmb3JtYXQgdGhlIElTVFJFQU0gYW5kIFNFTlRSWSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgdy9vIHdyaXRpbmcKICAgIC8vIG91dCBhbnkgb3V0cHV0CiAgICByd19mcHJpbnRmICgwLAogICAgICAgICAgICAgICAgIiV7JElTVFJFQU0hOkB9IiwKICAgICAgICAgICAgICAgICIlez99aXN0cmVhbSV7On0lez99d2lzdHJlYW0iCiAgICAgICAgICAgICAgICAiJXs6fWJhc2ljX2lzdHJlYW08JXMsICVzPiV7O30lezt9IiwKICAgICAgICAgICAgICAgICdjJyA9PSAqY25hbWUgJiYgJ2MnID09ICp0bmFtZSwgCiAgICAgICAgICAgICAgICAndycgPT0gKmNuYW1lICYmICdjJyA9PSAqdG5hbWUsCiAgICAgICAgICAgICAgICBjbmFtZSwgdG5hbWUpOwoKICAgIHJ3X2ZwcmludGYgKDAsCiAgICAgICAgICAgICAgICAiJXskU0VOVFJZITpAfSIsCiAgICAgICAgICAgICAgICAiJXskSVNUUkVBTX06OnNlbnRyeSIpOwoKICAgIC8vIHBhc3MgZm5hbWUgdGhyb3VnaCB0aGUgIiV7QH0iIGRpcmVjdGl2ZSB0byBleHBhbmQgYW55IGVtYmVkZGVkCiAgICAvLyAleyRYWVp9IGRpcmVjdGl2ZXMKICAgIHJ3X2luZm8gKDAsIDAsIGxpbmUsICJzdGQ6OiV7JFNFTlRSWX06OiV7QH0iLCBmbmFtZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnRlbXBsYXRlIDxjbGFzcyBjaGFyVD4Kc3RydWN0IEN0eXBlOiBzdGQ6OmN0eXBlPGNoYXJUPgp7CiAgICB0eXBlZGVmIHN0ZDo6Y3R5cGU8Y2hhclQ+IEJhc2U7CgogICAgY29uc3QgY2hhclQgd3NfOyAgIC8vIHdoaXRlc3BhY2UgY2hhcmFjdGVyCgogICAgc3RkOjpjdHlwZV9iYXNlOjptYXNrIHRhYmxlXyBbMjU2XTsKCiAgICBDdHlwZSAodW5zaWduZWQgcmVmLCBjaGFyVCB3aGl0ZSkKICAgICAgICA6IEJhc2UgKHJlZiksIHdzXyAod2hpdGUpIHsgfQoKICAgIC8vIHZpcnR1YWxzIG92ZXJyaWRkZW4gYmVsb3cgdXNlZCBieSBjdHlwZTx3Y2hhcl90PgogICAgLy8gY3R5cGU8Y2hhcj4gdXNlcyB0aGUgdGFibGUoKSBtZW1iZXIgaW5zdGVhZAoKICAgIC8qIHZpcnR1YWwgKi8gYm9vbAogICAgZG9faXMgKHN0ZDo6Y3R5cGVfYmFzZTo6bWFzayBtLCBjaGFyVCBjKSBjb25zdCB7CiAgICAgICAgaWYgKG0gJiBzdGQ6OmN0eXBlX2Jhc2U6OnNwYWNlKQogICAgICAgICAgICByZXR1cm4gd3NfID09IGM7CiAgICAgICAgcmV0dXJuIEJhc2U6OmlzIChtLCBjKTsKICAgIH0KCiAgICAvKiB2aXJ0dWFsICovIGNvbnN0IGNoYXJUKgogICAgZG9faXMgKGNvbnN0IGNoYXJUICpmcm9tLCBjb25zdCBjaGFyVCAqdG8sCiAgICAgICAgICAgc3RkOjpjdHlwZV9iYXNlOjptYXNrICptKSBjb25zdCB7CiAgICAgICAgcmV0dXJuIEJhc2U6OmlzIChmcm9tLCB0bywgbSk7CiAgICB9CgogICAgLyogdmlydHVhbCAqLyBjb25zdCBjaGFyVCoKICAgIGRvX3NjYW5faXMgKHN0ZDo6Y3R5cGVfYmFzZTo6bWFzayBtLAogICAgICAgICAgICAgICAgIGNvbnN0IGNoYXJUICpmcm9tLCBjb25zdCBjaGFyVCAqdG8pIGNvbnN0IHsKICAgICAgICBmb3IgKDsgZnJvbSAhPSB0byAmJiAhZG9faXMgKG0sICpmcm9tKTsgKytmcm9tKTsKICAgICAgICByZXR1cm4gZnJvbTsKICAgIH0KCiAgICAvKiB2aXJ0dWFsICovIGNvbnN0IGNoYXJUKgogICAgZG9fc2Nhbl9ub3QgKHN0ZDo6Y3R5cGVfYmFzZTo6bWFzayBtLAogICAgICAgICAgICAgICAgIGNvbnN0IGNoYXJUICpmcm9tLCBjb25zdCBjaGFyVCAqdG8pIGNvbnN0IHsKICAgICAgICBmb3IgKDsgZnJvbSAhPSB0byAmJiBkb19pcyAobSwgKmZyb20pOyArK2Zyb20pOwogICAgICAgIHJldHVybiBmcm9tOwogICAgfQp9OwoKCi8vIHNwZWNpYWxpemVkIGZvciBjdHlwZTxjaGFyPgpfUldTVERfU1BFQ0lBTElaRURfQ0xBU1MKQ3R5cGU8Y2hhcj46OkN0eXBlICh1bnNpZ25lZCByZWYsIGNoYXIgd2hpdGUpCiAgICA6IEJhc2UgKHRhYmxlXywgZmFsc2UsIHJlZiksIHdzXyAod2hpdGUpCnsKICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgIT0gc2l6ZW9mIHRhYmxlXyAvIHNpemVvZiAqdGFibGVfOyArK2kpCiAgICAgICAgdGFibGVfIFtpXSA9IHN0ZDo6Y3R5cGVfYmFzZTo6bWFzayAoKTsKCiAgICB0eXBlZGVmIHVuc2lnbmVkIGNoYXIgVUNoYXI7CgogICAgdGFibGVfIFtVQ2hhciAod3NfKV0gPSBzdGQ6OmN0eXBlX2Jhc2U6OnNwYWNlOwp9CgoKdGVtcGxhdGUgPGNsYXNzIGNoYXJULCBjbGFzcyBUcmFpdHM+CnN0cnVjdCBTdHJlYW1idWY6IHN0ZDo6YmFzaWNfc3RyZWFtYnVmPGNoYXJULCBUcmFpdHM+CnsKICAgIHR5cGVkZWYgc3RkOjpiYXNpY19zdHJlYW1idWY8Y2hhclQsIFRyYWl0cz4gQmFzZTsKCiAgICBpbnQgbnN5bmNzXzsKCiAgICBTdHJlYW1idWYgKGNvbnN0IGNoYXJUICpnYmVnLCBjb25zdCBjaGFyVCAqZ2VuZCkKICAgICAgICA6IEJhc2UgKCksIG5zeW5jc18gKDApIHsKICAgICAgICB0aGlzLT5zZXRnIChfUldTVERfQ09OU1RfQ0FTVCAoY2hhclQqLCBnYmVnKSwKICAgICAgICAgICAgICAgICAgICBfUldTVERfQ09OU1RfQ0FTVCAoY2hhclQqLCBnYmVnKSwKICAgICAgICAgICAgICAgICAgICBfUldTVERfQ09OU1RfQ0FTVCAoY2hhclQqLCBnZW5kKSk7CiAgICB9CgogICAgY29uc3QgY2hhclQqIHB1YmViYWNrICgpIGNvbnN0IHsKICAgICAgICByZXR1cm4gdGhpcy0+ZWJhY2sgKCk7CiAgICB9CgogICAgY29uc3QgY2hhclQqIHB1YmdwdHIgKCkgY29uc3QgewogICAgICAgIHJldHVybiB0aGlzLT5ncHRyICgpOwogICAgfQoKICAgIGNvbnN0IGNoYXJUKiBwdWJlZ3B0ciAoKSBjb25zdCB7CiAgICAgICAgcmV0dXJuIHRoaXMtPmVncHRyICgpOwogICAgfQoKICAgIC8qIHZpcnR1YWwgKi8gaW50IHN5bmMgKCkgewogICAgICAgICsrbnN5bmNzXzsKICAgICAgICByZXR1cm4gQmFzZTo6c3luYyAoKTsKICAgIH0KfTsKCgp0ZW1wbGF0ZSA8Y2xhc3MgY2hhclQsIGNsYXNzIFRyYWl0cz4Kdm9pZCB0ZXN0X2N0b3IgKGNvbnN0IGNoYXJUKiwgY29uc3QgVHJhaXRzKiwKICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNuYW1lLCBjb25zdCBjaGFyICp0bmFtZSkKewogICAgdHlwZWRlZiBzdGQ6OmJhc2ljX2lzdHJlYW08Y2hhclQsIFRyYWl0cz4gICBJc3RyZWFtOwogICAgdHlwZWRlZiB0eXBlbmFtZSBJc3RyZWFtOjpzZW50cnkgICAgICAgICAgICBTZW50cnk7CgogICAgbWVtZnVuX2luZm8gKF9fTElORV9fLCBjbmFtZSwgdG5hbWUsICJzZW50cnkgKCV7JElTVFJFQU19JiwgYm9vbCkiKTsKCiAgICBjb25zdCBjaGFyVCBjYnVmW10gPSB7ICdhJywgJ2InLCAnYycsICdkJywgJ2UnLCAnICcsICdmJywgJ1wwJyB9OwoKICAgIGNvbnN0IHN0ZDo6aW9zX2Jhc2U6Omlvc3RhdGUgc3RhdGVzW10gPSB7CiAgICAgICAgc3RkOjppb3NfYmFzZTo6YmFkYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6OmVvZmJpdCwKICAgICAgICBzdGQ6Omlvc19iYXNlOjpmYWlsYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6Omdvb2RiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6YmFkYml0IHwgc3RkOjppb3NfYmFzZTo6ZW9mYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6OmJhZGJpdCB8IHN0ZDo6aW9zX2Jhc2U6OmZhaWxiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6ZW9mYml0IHwgc3RkOjppb3NfYmFzZTo6ZmFpbGJpdCwKICAgICAgICBzdGQ6Omlvc19iYXNlOjpiYWRiaXQgfCBzdGQ6Omlvc19iYXNlOjplb2ZiaXQgfCBzdGQ6Omlvc19iYXNlOjpmYWlsYml0CiAgICB9OwoKICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvLyBleGVyY2lzZSAyNy42LjEuMS4yLCBwMToKICAgIC8vICAgICAtICBpcy5nb29kKCkgaXMgdHJ1ZQogICAgLy8gICAgIC0gIGlzLnRpZSgpIGlzIG5vdCBudWxsCiAgICAvLyAgICAgPSAgdGhlIGZ1bmN0aW9uIGNhbGxzIGlzLnRpZSgpLmZsdXNoKCkKCiAgICB1bnNpZ25lZCBpdGVyID0gMDsgICAgIC8vIGl0ZXJhdGlvbiBjb3VudGVyCgogICAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSAhPSBzaXplb2Ygc3RhdGVzIC8gc2l6ZW9mICpzdGF0ZXM7ICsraSkgewogICAgICAgIGZvciAodW5zaWduZWQgaiA9IDA7IGogIT0gMjsgKytqIC8qIG5vc2tpcHdzICovKSB7CiAgICAgICAgICAgIFN0cmVhbWJ1ZjxjaGFyVCwgVHJhaXRzPgogICAgICAgICAgICAgICAgc2IgKGNidWYsIGNidWYgKyBzaXplb2YgY2J1ZiAvIHNpemVvZiAqY2J1Zik7CgogICAgICAgICAgICBJc3RyZWFtIGlzICgmc2IpOwoKICAgICAgICAgICAgLy8gZmx1c2goKSBpcyBjYWxsZWQgaWZmCiAgICAgICAgICAgIC8vIGFsbCBvZiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgaG9sZAogICAgICAgICAgICBjb25zdCBib29sIGZsdXNoX2NhbGxlZCA9IGlzLmdvb2QgKCkgJiYgMCAhPSBpcy50aWUgKCk7CgogICAgICAgICAgICBjb25zdCBTZW50cnkgZ3VhcmQgKGlzLCAwICE9IGopOwoKICAgICAgICAgICAgX1JXU1REX1VOVVNFRCAoZ3VhcmQpOwoKICAgICAgICAgICAgcndfYXNzZXJ0IChmbHVzaF9jYWxsZWQgPT0gc2IubnN5bmNzXywgMCwgX19MSU5FX18sCiAgICAgICAgICAgICAgICAgICAgICAgIiV1LiBiYXNpY19pc3RyZWFtPCVzLCAlcz46OnNlbnRyeTo6c2VudHJ5IgogICAgICAgICAgICAgICAgICAgICAgICIoYmFzaWNfaXN0cmVhbSAmaXMsIGJvb2wgbm9za2lwd3MgPSAlZCk7ICIKICAgICAgICAgICAgICAgICAgICAgICAiZXhwZWN0ZWQgdG8gY2FsbCBpcy5mbHVzaCAoKSAlZCB0aW1lcywgZ290ICVkIgogICAgICAgICAgICAgICAgICAgICAgICJpbml0aWFsIGlzLnN0YXRlICgpID0gJXtJc30sIGlzLmZsYWdzKCkgJiAiCiAgICAgICAgICAgICAgICAgICAgICAgImlvczo6c2tpcHdzID0gJWQiLAogICAgICAgICAgICAgICAgICAgICAgIGl0ZXIsIGNuYW1lLCB0bmFtZSwgMCAhPSBqLCBmbHVzaF9jYWxsZWQsIHNiLm5zeW5jc18sCiAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVzIFtpXSwgaXMuZmxhZ3MgKCkgJiBzdGQ6Omlvc19iYXNlOjpza2lwd3MpOwoKICAgICAgICAgICAgKytpdGVyOwogICAgICAgIH0KICAgIH0KCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgLy8gZXhlcmNpc2UgMjcuNi4xLjEuMiwgcDE6CiAgICAvLyAgICAgLSAgaXMuZ29vZCgpIGlzIHRydWUKICAgIC8vICAgICAtICBub3NraXB3cyBpcyB6ZXJvCiAgICAvLyAgICAgLSAgaXMuZmxhZ3MoKSAmIGlvc19iYXNlOjpza2lwd3MKICAgIC8vICAgICA9ICB0aGUgZnVuY3Rpb24gZXh0cmFjdHMgYW5kIGRpc2NhcmRzIGVhY2ggY2hhcmFjdGVyIGFzIGxvbmcKICAgIC8vICAgICAgICBhcyB0aGUgbmV4dCBhdmFpbGFibGUgaW5wdXQgY2hhcmFjdGVyIGMgaXMgYSB3aGl0ZXNwYWNlCiAgICAvLyAgICAgICAgY2hhcmFjdGVyLgoKICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgIT0gc2l6ZW9mIHN0YXRlcyAvIHNpemVvZiAqc3RhdGVzOyArK2kpIHsKICAgICAgICBmb3IgKHVuc2lnbmVkIGogPSAwOyBqICE9IDI7ICsraiAvKiBub3NraXB3cyAqLykgewogICAgICAgICAgICBmb3IgKHVuc2lnbmVkIGsgPSAwOyBrICE9IDI7ICsrayAvKiBpb3NfYmFzZTo6c2tpcHdzICovKSB7CiAgICAgICAgICAgICAgICBmb3IgKGNoYXJUIHdjID0gY2hhclQgKCdhJyk7IHdjICE9IGNoYXJUICgnYycpOyArK3djKSB7CgogICAgICAgICAgICAgICAgICAgIGNvbnN0IEN0eXBlPGNoYXJUPiBjdHAgKDEsIHdjKTsKCiAgICAgICAgICAgICAgICAgICAgU3RyZWFtYnVmPGNoYXJULCBUcmFpdHM+CiAgICAgICAgICAgICAgICAgICAgICAgIHNiIChjYnVmLCBjYnVmICsgc2l6ZW9mIGNidWYgLyBzaXplb2YgKmNidWYpOwoKICAgICAgICAgICAgICAgICAgICBJc3RyZWFtIGlzICgmc2IpOwoKICAgICAgICAgICAgICAgICAgICBpcy5zZXRzdGF0ZSAoc3RhdGVzIFtpXSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChrKQogICAgICAgICAgICAgICAgICAgICAgICBpcy5zZXRmIChzdGQ6Omlvc19iYXNlOjpza2lwd3MpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgaXMudW5zZXRmIChzdGQ6Omlvc19iYXNlOjpza2lwd3MpOwoKICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OmxvY2FsZSBsb2MgPSAKICAgICAgICAgICAgICAgICAgICAgICAgaXMuaW1idWUgKHN0ZDo6bG9jYWxlIChpcy5nZXRsb2MgKCksICZjdHApKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gaW1idWUgdGhlIHByZXZpb3VzIGxvY2FsZSBpbnRvIHRoZSBzdHJlYW0KICAgICAgICAgICAgICAgICAgICAvLyBidWZmZXIgdG8gdmVyaWZ5IHRoYXQgdGhlIHNlbnRyeSBjdG9yIHVzZXMKICAgICAgICAgICAgICAgICAgICAvLyB0aGUgbG9jYWxlIGltYnVlZCBpbiB0aGUgc3RyZWFtIG9iamVjdCBhbmQKICAgICAgICAgICAgICAgICAgICAvLyBub3QgdGhlIG9uZSBpbiB0aGUgc3RyZWFtIGJ1ZmZlcgogICAgICAgICAgICAgICAgICAgIHNiLnB1YmltYnVlIChsb2MpOwoKICAgICAgICAgICAgICAgICAgICAvLyBhIHdoaXRlc3BhY2UgY2hhcmFjdGVyIGlzIGV4dHJhY3RlZCBpZmYKICAgICAgICAgICAgICAgICAgICAvLyBhbGwgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGhvbGQKICAgICAgICAgICAgICAgICAgICBjb25zdCBib29sIGV4dHJhY3QgPQogICAgICAgICAgICAgICAgICAgICAgICAgICBpcy5nb29kICgpCiAgICAgICAgICAgICAgICAgICAgICAgICYmIDAgPT0gagogICAgICAgICAgICAgICAgICAgICAgICAmJiBpcy5mbGFncyAoKSAmIHN0ZDo6aW9zX2Jhc2U6OnNraXB3cwogICAgICAgICAgICAgICAgICAgICAgICAmJiBjYnVmIFswXSA9PSB3YzsKCiAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VudHJ5IGd1YXJkIChpcywgMCAhPSBqKTsKCiAgICAgICAgICAgICAgICAgICAgX1JXU1REX1VOVVNFRCAoZ3VhcmQpOwoKICAgICAgICAgICAgICAgICAgICByd19hc3NlcnQgKGNidWYgKyBleHRyYWN0ID09IHNiLnB1YmdwdHIgKCksIDAsIF9fTElORV9fLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIldS4gJXskU0VOVFJZfTo6c2VudHJ5IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigleyRJU1RSRUFNfSAmaXMsIGJvb2wgbm9za2lwd3MgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIj0gJWIpOyBleHBlY3RlZCB0byBleHRyYWN0ICVkICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3aGl0ZXNwYWNlIGNoYXJzICgnJWMnKSBmcm9tICV7KkFjfSwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImV4dHJhY3RlZCAldTsgaW5pdGlhbCBpcy5zdGF0ZSAoKSA9ICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIle0lzfSwgaXMuZmxhZ3MoKSAmIGlvczo6c2tpcHdzID0gJWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciwgaiwgZXh0cmFjdCArIDAsIGNoYXIgKHdjKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAoc2l6ZW9mICgqY2J1ZikpLCBjYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2IucHViZ3B0ciAoKSAtIHNiLnB1YmViYWNrICgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVzIFtpXSwgayk7CgogICAgICAgICAgICAgICAgICAgIC8vIHZlcmlmeSB0aGF0IHRoZSBjdG9yIGRvZXNuJ3QgYWZmZWN0IGdjb3VudCgpCiAgICAgICAgICAgICAgICAgICAgcndfYXNzZXJ0ICgwID09IGlzLmdjb3VudCAoKSwgMCwgX19MSU5FX18sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiV1LiAleyRTRU5UUll9OjpzZW50cnkiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCV7JElTVFJFQU19ICZpcyA9ICV7KkFjfSwgYm9vbCBub3NraXB3cyAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPSAlYik7IGNoYW5nZWQgaXMuZ2NvdW50KCkgZnJvbSAwIHRvICVpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIsIGludCAoc2l6ZW9mICgqY2J1ZikpLCBjYnVmLCBqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMuZ2NvdW50ICgpKTsKCiAgICAgICAgICAgICAgICAgICAgKytpdGVyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp0ZW1wbGF0ZSA8Y2xhc3MgY2hhclQsIGNsYXNzIFRyYWl0cz4Kdm9pZCB0ZXN0X29rIChjb25zdCBjaGFyVCosIGNvbnN0IFRyYWl0cyosCiAgICAgICAgICAgICAgY29uc3QgY2hhciAqY25hbWUsIGNvbnN0IGNoYXIgKnRuYW1lKQp7CiAgICB0eXBlZGVmIHN0ZDo6YmFzaWNfaXN0cmVhbTxjaGFyVCwgVHJhaXRzPiAgIElzdHJlYW07CiAgICB0eXBlZGVmIHR5cGVuYW1lIElzdHJlYW06OnNlbnRyeSAgICAgICAgICAgIFNlbnRyeTsKCiAgICBtZW1mdW5faW5mbyAoX19MSU5FX18sIGNuYW1lLCB0bmFtZSwgIm9wZXJhdG9yIGJvb2wgKCkgY29uc3QiKTsKCiAgICBjb25zdCBjaGFyVCBjYnVmW10gPSB7ICdhJywgJ2InLCAnYycsICdkJywgJ2UnLCAnICcsICdmJywgJ1wwJyB9OwoKICAgIGNvbnN0IHN0ZDo6aW9zX2Jhc2U6Omlvc3RhdGUgc3RhdGVzW10gPSB7CiAgICAgICAgc3RkOjppb3NfYmFzZTo6YmFkYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6OmVvZmJpdCwKICAgICAgICBzdGQ6Omlvc19iYXNlOjpmYWlsYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6Omdvb2RiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6YmFkYml0IHwgc3RkOjppb3NfYmFzZTo6ZW9mYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6OmJhZGJpdCB8IHN0ZDo6aW9zX2Jhc2U6OmZhaWxiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6ZW9mYml0IHwgc3RkOjppb3NfYmFzZTo6ZmFpbGJpdCwKICAgICAgICBzdGQ6Omlvc19iYXNlOjpiYWRiaXQgfCBzdGQ6Omlvc19iYXNlOjplb2ZiaXQgfCBzdGQ6Omlvc19iYXNlOjpmYWlsYml0CiAgICB9OwoKICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvLyBleGVyY2lzZSAyNy42LjEuMS4yLCBwNToKICAgIC8vICAgICAtICBpcy5nb29kKCkgaXMgdHJ1ZQogICAgLy8gICAgIC0gIG5vc2tpcHdzIGlzIHplcm8KICAgIC8vICAgICAtICBpcy5mbGFncygpICYgaW9zX2Jhc2U6OnNraXB3cwogICAgLy8gICAgIC0gIHRoZSBmdW5jdGlvbiBleHRyYWN0cyBhbmQgZGlzY2FyZHMgZWFjaCBjaGFyYWN0ZXIgYXMgbG9uZwogICAgLy8gICAgICAgIGFzIHRoZSBuZXh0IGF2YWlsYWJsZSBpbnB1dCBjaGFyYWN0ZXIgYyBpcyBhIHdoaXRlc3BhY2UKICAgIC8vICAgICAgICBjaGFyYWN0ZXIKICAgIC8vICAgICA9ICBpZiwgYWZ0ZXIgYW55IHByZXBhcmF0aW9uIGlzIGNvbXBsZXRlZCwgaXMuZ29vZCgpIGlzIHRydWUsCiAgICAvLyAgICAgICAgb2tfICE9IGZhbHNlIG90aGVyd2lzZSwgb2tfID09IGZhbHNlLgoKICAgIHVuc2lnbmVkIGl0ZXIgPSAwOyAgICAgLy8gaXRlcmF0aW9uIGNvdW50ZXIKCiAgICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBpICE9IHNpemVvZiBzdGF0ZXMgLyBzaXplb2YgKnN0YXRlczsgKytpKSB7CiAgICAgICAgZm9yICh1bnNpZ25lZCBqID0gMDsgaiAhPSAyOyArK2ogLyogbm9za2lwd3MgKi8pIHsKICAgICAgICAgICAgZm9yICh1bnNpZ25lZCBrID0gMDsgayAhPSAyOyArK2sgLyogaW9zX2Jhc2U6OnNraXB3cyAqLykgewogICAgICAgICAgICAgICAgZm9yIChjaGFyVCB3YyA9IGNoYXJUICgnYScpOyB3YyAhPSBjaGFyVCAoJ2MnKTsgKyt3YykgewoKICAgICAgICAgICAgICAgICAgICBjb25zdCBDdHlwZTxjaGFyVD4gY3RwICgxLCB3Yyk7CgogICAgICAgICAgICAgICAgICAgIFN0cmVhbWJ1ZjxjaGFyVCwgVHJhaXRzPgogICAgICAgICAgICAgICAgICAgICAgICBzYiAoY2J1ZiwgY2J1ZiArIHNpemVvZiBjYnVmIC8gc2l6ZW9mICpjYnVmKTsKCiAgICAgICAgICAgICAgICAgICAgSXN0cmVhbSBpcyAoJnNiKTsKCiAgICAgICAgICAgICAgICAgICAgaXMuc2V0c3RhdGUgKHN0YXRlcyBbaV0pOwoKICAgICAgICAgICAgICAgICAgICBpZiAoaykKICAgICAgICAgICAgICAgICAgICAgICAgaXMuc2V0ZiAoc3RkOjppb3NfYmFzZTo6c2tpcHdzKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIGlzLnVuc2V0ZiAoc3RkOjppb3NfYmFzZTo6c2tpcHdzKTsKCiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjpsb2NhbGUgbG9jID0gCiAgICAgICAgICAgICAgICAgICAgICAgIGlzLmltYnVlIChzdGQ6OmxvY2FsZSAoaXMuZ2V0bG9jICgpLCAmY3RwKSk7CgogICAgICAgICAgICAgICAgICAgIC8vIGltYnVlIHRoZSBwcmV2aW91cyBsb2NhbGUgaW50byB0aGUgc3RyZWFtCiAgICAgICAgICAgICAgICAgICAgLy8gYnVmZmVyIHRvIHZlcmlmeSB0aGF0IHRoZSBzZW50cnkgY3RvciB1c2VzCiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGxvY2FsZSBpbWJ1ZWQgaW4gdGhlIHN0cmVhbSBvYmplY3QgYW5kCiAgICAgICAgICAgICAgICAgICAgLy8gbm90IHRoZSBvbmUgaW4gdGhlIHN0cmVhbSBidWZmZXIKICAgICAgICAgICAgICAgICAgICBzYi5wdWJpbWJ1ZSAobG9jKTsKCiAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VudHJ5IGd1YXJkIChpcywgMCAhPSBqKTsKCiAgICAgICAgICAgICAgICAgICAgX1JXU1REX1VOVVNFRCAoZ3VhcmQpOwoKICAgICAgICAgICAgICAgICAgICBjb25zdCBib29sIHN1Y2Nlc3MgPQogICAgICAgICAgICAgICAgICAgICAgICAgICBpcy5nb29kICgpICYmIGd1YXJkCiAgICAgICAgICAgICAgICAgICAgICAgIHx8ICFpcy5nb29kICgpICYmICFndWFyZDsKCiAgICAgICAgICAgICAgICAgICAgcndfYXNzZXJ0IChzdWNjZXNzLCAwLCBfX0xJTkVfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIldS4gJXskU0VOVFJZfSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoJXskSVNUUkVBTX0gJmlzLCBib29sIG5vc2tpcHdzICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI9ICVkKS5vcGVyYXRvciBib29sKCkgPT0gJWQ7IGluaXRpYWwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImlzLnN0YXRlKCkgPSAle0lzfSwgaXMuZmxhZ3MoKSAmICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpb3M6OnNraXB3cyA9ICVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIsIGosIGlzLmdvb2QgKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZXMgW2ldLCBrKTsKCiAgICAgICAgICAgICAgICAgICAgKytpdGVyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgaW50IG9wdF9jaGFyOwpzdGF0aWMgaW50IG9wdF93Y2hhcjsKc3RhdGljIGludCBvcHRfY2hhcl90cmFpdHM7CnN0YXRpYyBpbnQgb3B0X3VzZXJfdHJhaXRzOwoKCnN0YXRpYyBpbnQKcnVuX3Rlc3QgKGludCwgY2hhcioqKQp7CiNkZWZpbmUgVEVTVCh3aGF0LCBjaGFyVCwgVHJhaXRzKSBcCiAgICB0ZXN0XyAjIyB3aGF0ICgoY2hhclQqKTAsIChUcmFpdHMqKTAsICNjaGFyVCwgI1RyYWl0cykKCiAgICB1c2luZyBuYW1lc3BhY2Ugc3RkOwoKICAgIGlmIChyd19ub3RlICgwIDw9IG9wdF9jaGFyICYmIDAgPD0gb3B0X2NoYXJfdHJhaXRzLCAwLCBfX0xJTkVfXywKICAgICAgICAgICAgICAgICAiaXN0cmVhbTo6c2VudHJ5IHRlc3RzIGRpc2FibGVkIikpIHsKICAgICAgICBURVNUIChjdG9yLCBjaGFyLCBjaGFyX3RyYWl0czxjaGFyPik7CiAgICAgICAgVEVTVCAob2ssIGNoYXIsIGNoYXJfdHJhaXRzPGNoYXI+KTsKICAgIH0KCiAgICBpZiAocndfbm90ZSAoMCA8PSBvcHRfY2hhciAmJiAwIDw9IG9wdF91c2VyX3RyYWl0cywgMCwgX19MSU5FX18sCiAgICAgICAgICAgICAgICAgImJhc2ljX2lzdHJlYW08Y2hhciwgVXNlclRyYWl0czxjaGFyPjo6c2VudHJ5ICIKICAgICAgICAgICAgICAgICAidGVzdHMgZGlzYWJsZWQiKSkgewogICAgICAgIFRFU1QgKGN0b3IsIGNoYXIsIFVzZXJUcmFpdHM8Y2hhcj4pOwogICAgICAgIFRFU1QgKG9rLCBjaGFyLCBVc2VyVHJhaXRzPGNoYXI+KTsKICAgIH0KCiNpZm5kZWYgX1JXU1REX05PX1dDSEFSX1QKCiAgICBpZiAocndfbm90ZSAoMCA8PSBvcHRfd2NoYXIgJiYgMCA8PSBvcHRfY2hhcl90cmFpdHMsIDAsIF9fTElORV9fLAogICAgICAgICAgICAgICAgICJ3aXN0cmVhbTo6c2VudHJ5IHRlc3RzIGRpc2FibGVkIikpIHsKICAgICAgICBURVNUIChjdG9yLCB3Y2hhcl90LCBjaGFyX3RyYWl0czx3Y2hhcl90Pik7CiAgICAgICAgVEVTVCAob2ssIHdjaGFyX3QsIGNoYXJfdHJhaXRzPHdjaGFyX3Q+KTsKICAgIH0KCiAgICBpZiAocndfbm90ZSAoMCA8PSBvcHRfd2NoYXIgJiYgMCA8PSBvcHRfdXNlcl90cmFpdHMsIDAsIF9fTElORV9fLAogICAgICAgICAgICAgICAgICJiYXNpY19pc3RyZWFtPHdjaGFyX3QsIFVzZXJUcmFpdHM8d2NoYXJfdD46OnNlbnRyeSAiCiAgICAgICAgICAgICAgICAgInRlc3RzIGRpc2FibGVkIikpIHsKICAgICAgICBURVNUIChjdG9yLCB3Y2hhcl90LCBVc2VyVHJhaXRzPHdjaGFyX3Q+KTsKICAgICAgICBURVNUIChvaywgd2NoYXJfdCwgVXNlclRyYWl0czx3Y2hhcl90Pik7CiAgICB9CgojZW5kaWYgICAvLyBfUldTVERfTk9fV0NIQVJfVAoKICAgIHJldHVybiAwOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKaW50IG1haW4gKGludCBhcmdjLCBjaGFyICphcmd2W10pCnsKICAgIHJldHVybiByd190ZXN0IChhcmdjLCBhcmd2LCBfX0ZJTEVfXywKICAgICAgICAgICAgICAgICAgICAiaXN0cmVhbS5zZW50cnkiLAogICAgICAgICAgICAgICAgICAgIDAgLyogbm8gY29tbWVudCAqLywKICAgICAgICAgICAgICAgICAgICBydW5fdGVzdCwKICAgICAgICAgICAgICAgICAgICAifC1jaGFyfiAiCiAgICAgICAgICAgICAgICAgICAgInwtd2NoYXJfdH4gIgogICAgICAgICAgICAgICAgICAgICJ8LWNoYXJfdHJhaXRzfiAiCiAgICAgICAgICAgICAgICAgICAgInwtVXNlclRyYWl0c34gIiwKICAgICAgICAgICAgICAgICAgICAmb3B0X2NoYXIsCiAgICAgICAgICAgICAgICAgICAgJm9wdF93Y2hhciwKICAgICAgICAgICAgICAgICAgICAmb3B0X2NoYXJfdHJhaXRzLAogICAgICAgICAgICAgICAgICAgICZvcHRfdXNlcl90cmFpdHMsCiAgICAgICAgICAgICAgICAgICAgKHZvaWQqKTAgICAvKiBzZW50aW5lbCAqLyk7Cn0K