LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBpc3RyZWFtX3NlbnRyeS5jcHAgLSB0ZXN0IGV4ZXJjaXNpbmcgYmFzaWNfaXN0cmVhbTxjaGFyVD46OnNlbnRyeQogKgogKiAkSWQkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSAgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUgb3IgbW9yZQogKiBjb250cmlidXRvciAgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlICB0aGUgTk9USUNFICBmaWxlIGRpc3RyaWJ1dGVkCiAqIHdpdGggIHRoaXMgIHdvcmsgIGZvciAgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiAgcmVnYXJkaW5nICBjb3B5cmlnaHQKICogb3duZXJzaGlwLiAgIFRoZSBBU0YgIGxpY2Vuc2VzIHRoaXMgIGZpbGUgdG8gIHlvdSB1bmRlciAgdGhlIEFwYWNoZQogKiBMaWNlbnNlLCBWZXJzaW9uICAyLjAgKHRoZSAgIkxpY2Vuc2UiKTsgeW91IG1heSAgbm90IHVzZSAgdGhpcyBmaWxlCiAqIGV4Y2VwdCBpbiAgY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiAgIFlvdSBtYXkgb2J0YWluICBhIGNvcHkgb2YKICogdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlICBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUICBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgIE9GIEFOWSAgS0lORCwgZWl0aGVyICBleHByZXNzIG9yCiAqIGltcGxpZWQuICAgU2VlICB0aGUgTGljZW5zZSAgZm9yICB0aGUgIHNwZWNpZmljIGxhbmd1YWdlICBnb3Zlcm5pbmcKICogcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKgogKiBDb3B5cmlnaHQgMjAwMy0yMDA2IFJvZ3VlIFdhdmUgU29mdHdhcmUsIEluYy4KICogCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlIDxpc3RyZWFtPgojaW5jbHVkZSA8bG9jYWxlPiAgICAgICAgLy8gZm9yIGN0eXBlCiNpbmNsdWRlIDxzdHJlYW1idWY+ICAgICAvLyBmb3Igc3RyZWFtYnVmCgojaW5jbHVkZSA8cndfY2hhci5oPiAgICAgLy8gZm9yIFVzZXJDaGFyLCBVc2VyVHJhaXRzCiNpbmNsdWRlIDxyd19wcmludGYuaD4gICAvLyBmb3IgcndfcHJpbnRmKCkKI2luY2x1ZGUgPHJ3X2RyaXZlci5oPgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIDI3LjYuMS4xLjIgICBDbGFzcyBiYXNpY19pc3RyZWFtOjpzZW50cnkgICBbbGliLmlzdHJlYW06OnNlbnRyeV0KCiAgICBuYW1lc3BhY2Ugc3RkIHsKICAgICAgICB0ZW1wbGF0ZSA8Y2xhc3MgY2hhclQsIGNsYXNzIHRyYWl0cyA9IGNoYXJfdHJhaXRzPGNoYXJUPiA+CiAgICAgICAgY2xhc3MgYmFzaWNfaXN0cmVhbTxjaGFyVCwgdHJhaXRzPjo6c2VudHJ5IHsKICAgICAgICAgICAgdHlwZWRlZiB0cmFpdHMgdHJhaXRzX3R5cGU7CiAgICAgICAgICAgIGJvb2wgb2tfOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBleHBvc2l0aW9uIG9ubHkKICAgICAgICBwdWJsaWM6CiAgICAgICAgICAgIGV4cGxpY2l0CiAgICAgICAgICAgIHNlbnRyeSAoYmFzaWNfaXN0cmVhbTxjaGFyVCwgdHJhaXRzPiYgaXMsIGJvb2wgbm9za2lwd3MgPSBmYWxzZSk7CiAgICAgICAgICAgIH5zZW50cnkgKCk7CiAgICAgICAgICAgIG9wZXJhdG9yIGJvb2woKSBjb25zdCB7IHJldHVybiBva187IH0KICAgICAgICBwcml2YXRlOgogICAgICAgICAgICBzZW50cnkgKGNvbnN0IHNlbnRyeSYpOyAgICAgICAgICAgICAgLy8gbm90IGRlZmluZWQKICAgICAgICAgICAgc2VudHJ5JiBvcGVyYXRvcj0gKGNvbnN0IHNlbnRyeSYpOyAgIC8vIG5vdCBkZWZpbmVkCiAgICAgICAgfTsKICAgIH0KCiAgICAtMS0gVGhlIGNsYXNzIHNlbnRyeSBkZWZpbmVzIGEgY2xhc3MgdGhhdCBpcyByZXNwb25zaWJsZSBmb3IgZG9pbmcKICAgICAgICBleGNlcHRpb24gc2FmZSBwcmVmaXggYW5kIHN1ZmZpeCBvcGVyYXRpb25zLgoKICAgIGV4cGxpY2l0IHNlbnRyeShiYXNpY19pc3RyZWFtPGNoYXJULCB0cmFpdHM+JiBpcywgYm9vbCBub3NraXB3cyA9IGZhbHNlKTsKICAgIC0yLSBFZmZlY3RzOiBJZiBpcy5nb29kKCkgaXMgdHJ1ZSwgcHJlcGFyZXMgZm9yIGZvcm1hdHRlZCBvciB1bmZvcm1hdHRlZAogICAgICAgIGlucHV0LiBGaXJzdCwgaWYgaXMudGllKCkgaXMgbm90IGEgbnVsbCBwb2ludGVyLCB0aGUgZnVuY3Rpb24gY2FsbHMKICAgICAgICBpcy50aWUoKa0+Zmx1c2goKSB0byBzeW5jaHJvbml6ZSB0aGUgb3V0cHV0IHNlcXVlbmNlIHdpdGggYW55CiAgICAgICAgYXNzb2NpYXRlZCBleHRlcm5hbCBDIHN0cmVhbS4gRXhjZXB0IHRoYXQgdGhpcyBjYWxsIGNhbiBiZSBzdXBwcmVzc2VkCiAgICAgICAgaWYgdGhlIHB1dCBhcmVhIG9mIGlzLnRpZSgpIGlzIGVtcHR5LiBGdXJ0aGVyIGFuIGltcGxlbWVudGF0aW9uIGlzCiAgICAgICAgYWxsb3dlZCB0byBkZWZlciB0aGUgY2FsbCB0byBmbHVzaCB1bnRpbCBhIGNhbGwgb2YKICAgICAgICBpcy0+cmRidWYoKa0+dW5kZXJmbG93IG9jY3Vycy4gSWYgbm8gc3VjaCBjYWxsIG9jY3VycyBiZWZvcmUgdGhlCiAgICAgICAgc2VudHJ5IG9iamVjdCBpcyBkZXN0cm95ZWQsIHRoZSBjYWxsIHRvIGZsdXNoIG1heSBiZSBlbGltaW5hdGVkCiAgICAgICAgZW50aXJlbHkoMjc5KS4gSWYgbm9za2lwd3MgaXMgemVybyBhbmQgaXMuZmxhZ3MoKSAmIGlvc19iYXNlOjpza2lwd3MKICAgICAgICBpcyBub256ZXJvLCB0aGUgZnVuY3Rpb24gZXh0cmFjdHMgYW5kIGRpc2NhcmRzIGVhY2ggY2hhcmFjdGVyIGFzIGxvbmcKICAgICAgICBhcyB0aGUgbmV4dCBhdmFpbGFibGUgaW5wdXQgY2hhcmFjdGVyIGMgaXMgYSB3aGl0ZXNwYWNlIGNoYXJhY3Rlci4KICAgIC0zLSBOb3RlczogVGhlIGNvbnN0cnVjdG9yIGV4cGxpY2l0IHNlbnRyeShiYXNpY19pc3RyZWFtPGNoYXJULCB0cmFpdHM+JgogICAgICAgIGlzLCBib29sIG5vc2tpcHdzID0gZmFsc2UpIHVzZXMgdGhlIGN1cnJlbnRseSBpbWJ1ZWQgbG9jYWxlIGluIGlzLAogICAgICAgIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBuZXh0IGlucHV0IGNoYXJhY3RlciBpcyB3aGl0ZXNwYWNlIG9yIG5vdC4KICAgIC00LSBUbyBkZWNpZGUgaWYgdGhlIGNoYXJhY3RlciBjaXMgYSB3aGl0ZXNwYWNlIGNoYXJhY3RlciwgdGhlIGNvbnN0cnVjdG9yCiAgICAgICAgcGVyZm9ybXMgImFzIGlmIiBpdCBleGVjdXRlcyB0aGUgZm9sbG93aW5nIGNvZGUgZnJhZ21lbnQ6CiAgICAgICAgY29uc3QgY3R5cGU8Y2hhclQ+JiBjdHlwZSA9IHVzZV9mYWNldDxjdHlwZTxjaGFyVD4gPihpcy5nZXRsb2MoKSk7CiAgICAgICAgaWYgKGN0eXBlLmlzIChjdHlwZS5zcGFjZSxjKSAhPSAwKQogICAgICAgICAgICAvLyBjIGlzIGEgd2hpdGVzcGFjZSBjaGFyYWN0ZXIuCiAgICAtNS0gSWYsIGFmdGVyIGFueSBwcmVwYXJhdGlvbiBpcyBjb21wbGV0ZWQsIGlzLmdvb2QoKSBpcyB0cnVlLAogICAgICAgIG9rXyAhPSBmYWxzZSBvdGhlcndpc2UsIG9rXyA9PSBmYWxzZS4gRHVyaW5nIHByZXBhcmF0aW9uLCB0aGUKICAgICAgICBjb25zdHJ1Y3RvciBtYXkgY2FsbCBzZXRzdGF0ZShmYWlsYml0KSAod2hpY2ggbWF5IHRocm93CiAgICAgICAgaW9zX2Jhc2U6OmZhaWx1cmUgKDI3LjQuNC4zKSkoMjgwKQogICAgX19fX19fX19fX19fX19fX19fCiAgICAyNzkpIFRoaXMgd2lsbCBiZSBwb3NzaWJsZSBvbmx5IGluIGZ1bmN0aW9ucyB0aGF0IGFyZSBwYXJ0IG9mIHRoZQogICAgICAgICBsaWJyYXJ5LiBUaGUgc2VtYW50aWNzIG9mIHRoZSBjb25zdHJ1Y3RvciB1c2VkIGluIHVzZXIgY29kZSBpcwogICAgICAgICBhcyBzcGVjaWZpZWQuCiAgICAyODApIFRoZSBzZW50cnkgY29uc3RydWN0b3IgYW5kIGRlc3RydWN0b3IgY2FuIGFsc28gcGVyZm9ybSBhZGRpdGlvbmFsCiAgICAgICAgIGltcGxlbWVudGF0aW9uLWRlcGVuZGVudCBvcGVyYXRpb25zLgoKICAgIC02LSBbRXhhbXBsZTogQSB0eXBpY2FsIGltcGxlbWVudGF0aW9uIG9mIHRoZSBzZW50cnkgY29uc3RydWN0b3IgbWlnaHQKICAgICAgICBpbmNsdWRlIGNvZGUgc3VjaCBhczoKCiAgICAgICAgdGVtcGxhdGUgPGNsYXNzIGNoYXJULCBjbGFzcyB0cmFpdHMgPSBjaGFyX3RyYWl0czxjaGFyVD4gPgogICAgICAgIGJhc2ljX2lzdHJlYW08Y2hhclQsdHJhaXRzPjo6c2VudHJ5KAogICAgICAgICAgICBiYXNpY19pc3RyZWFtPGNoYXJULHRyYWl0cz4mIGlzLCBib29sIG5vc2tpcHdzID0gZmFsc2UpIHsKICAgICAgICAgICAgLi4uCiAgICAgICAgICAgIGludF90eXBlIGM7CiAgICAgICAgICAgIHR5cGVkZWYgY3R5cGU8Y2hhclQ+IGN0eXBlX3R5cGU7CiAgICAgICAgICAgIGNvbnN0IGN0eXBlX3R5cGUmIGN0eXBlID0gdXNlX2ZhY2V0PGN0eXBlX3R5cGU+KGlzLmdldGxvYygpKTsKICAgICAgICAgICAgd2hpbGUgKChjID0gaXMucmRidWYoKa0+c25leHRjKCkpICE9IHRyYWl0czo6ZW9mKCkpIHsKICAgICAgICAgICAgICAgIGlmIChjdHlwZS5pcyhjdHlwZS5zcGFjZSxjKT09MCkgewogICAgICAgICAgICAgICAgICAgIGlzLnJkYnVmKCmtPnNwdXRiYWNrYyAoYyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLi4uCiAgICAgICAgfQogICAgICAgIC0tZW5kIGV4YW1wbGVdCgogICAgfnNlbnRyeSgpOwogICAgLTctIEVmZmVjdHM6IE5vbmUuCgogICAgb3BlcmF0b3IgYm9vbCgpIGNvbnN0OwogICAgLTgtIEVmZmVjdHM6IFJldHVybnMgb2tfLgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZAptZW1mdW5faW5mbyAoaW50IGxpbmUsIGNvbnN0IGNoYXIgKmNuYW1lLCBjb25zdCBjaGFyICp0bmFtZSwgY29uc3QgY2hhciAqZm5hbWUpCnsKICAgIC8vIGZvcm1hdCB0aGUgSVNUUkVBTSBhbmQgU0VOVFJZIGVudmlyb25tZW50IHZhcmlhYmxlcyB3L28gd3JpdGluZwogICAgLy8gb3V0IGFueSBvdXRwdXQKICAgIHJ3X2ZwcmludGYgKDAsCiAgICAgICAgICAgICAgICAiJXskSVNUUkVBTSE6QH0iLAogICAgICAgICAgICAgICAgIiV7P31pc3RyZWFtJXs6fSV7P313aXN0cmVhbSIKICAgICAgICAgICAgICAgICIlezp9YmFzaWNfaXN0cmVhbTwlcywgJXM+JXs7fSV7O30iLAogICAgICAgICAgICAgICAgJ2MnID09ICpjbmFtZSAmJiAnYycgPT0gKnRuYW1lLCAKICAgICAgICAgICAgICAgICd3JyA9PSAqY25hbWUgJiYgJ2MnID09ICp0bmFtZSwKICAgICAgICAgICAgICAgIGNuYW1lLCB0bmFtZSk7CgogICAgcndfZnByaW50ZiAoMCwKICAgICAgICAgICAgICAgICIleyRTRU5UUlkhOkB9IiwKICAgICAgICAgICAgICAgICIleyRJU1RSRUFNfTo6c2VudHJ5Iik7CgogICAgLy8gcGFzcyBmbmFtZSB0aHJvdWdoIHRoZSAiJXtAfSIgZGlyZWN0aXZlIHRvIGV4cGFuZCBhbnkgZW1iZWRkZWQKICAgIC8vICV7JFhZWn0gZGlyZWN0aXZlcwogICAgcndfaW5mbyAoMCwgMCwgbGluZSwgInN0ZDo6JXskU0VOVFJZfTo6JXtAfSIsIGZuYW1lKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdGVtcGxhdGUgPGNsYXNzIGNoYXJUPgpzdHJ1Y3QgQ3R5cGU6IHN0ZDo6Y3R5cGU8Y2hhclQ+CnsKICAgIHR5cGVkZWYgc3RkOjpjdHlwZTxjaGFyVD4gQmFzZTsKCiAgICBjb25zdCBjaGFyVCB3c187ICAgLy8gd2hpdGVzcGFjZSBjaGFyYWN0ZXIKCiAgICBzdGQ6OmN0eXBlX2Jhc2U6Om1hc2sgdGFibGVfIFsyNTZdOwoKICAgIEN0eXBlICh1bnNpZ25lZCByZWYsIGNoYXJUIHdoaXRlKQogICAgICAgIDogQmFzZSAocmVmKSwgd3NfICh3aGl0ZSkgeyB9CgogICAgLy8gdmlydHVhbHMgb3ZlcnJpZGRlbiBiZWxvdyB1c2VkIGJ5IGN0eXBlPHdjaGFyX3Q+CiAgICAvLyBjdHlwZTxjaGFyPiB1c2VzIHRoZSB0YWJsZSgpIG1lbWJlciBpbnN0ZWFkCgogICAgLyogdmlydHVhbCAqLyBib29sCiAgICBkb19pcyAoc3RkOjpjdHlwZV9iYXNlOjptYXNrIG0sIGNoYXJUIGMpIGNvbnN0IHsKICAgICAgICBpZiAobSAmIHN0ZDo6Y3R5cGVfYmFzZTo6c3BhY2UpCiAgICAgICAgICAgIHJldHVybiB3c18gPT0gYzsKICAgICAgICByZXR1cm4gQmFzZTo6aXMgKG0sIGMpOwogICAgfQoKICAgIC8qIHZpcnR1YWwgKi8gY29uc3QgY2hhclQqCiAgICBkb19pcyAoY29uc3QgY2hhclQgKmZyb20sIGNvbnN0IGNoYXJUICp0bywKICAgICAgICAgICBzdGQ6OmN0eXBlX2Jhc2U6Om1hc2sgKm0pIGNvbnN0IHsKICAgICAgICByZXR1cm4gQmFzZTo6aXMgKGZyb20sIHRvLCBtKTsKICAgIH0KCiAgICAvKiB2aXJ0dWFsICovIGNvbnN0IGNoYXJUKgogICAgZG9fc2Nhbl9pcyAoc3RkOjpjdHlwZV9iYXNlOjptYXNrIG0sCiAgICAgICAgICAgICAgICAgY29uc3QgY2hhclQgKmZyb20sIGNvbnN0IGNoYXJUICp0bykgY29uc3QgewogICAgICAgIGZvciAoOyBmcm9tICE9IHRvICYmICFkb19pcyAobSwgKmZyb20pOyArK2Zyb20pOwogICAgICAgIHJldHVybiBmcm9tOwogICAgfQoKICAgIC8qIHZpcnR1YWwgKi8gY29uc3QgY2hhclQqCiAgICBkb19zY2FuX25vdCAoc3RkOjpjdHlwZV9iYXNlOjptYXNrIG0sCiAgICAgICAgICAgICAgICAgY29uc3QgY2hhclQgKmZyb20sIGNvbnN0IGNoYXJUICp0bykgY29uc3QgewogICAgICAgIGZvciAoOyBmcm9tICE9IHRvICYmIGRvX2lzIChtLCAqZnJvbSk7ICsrZnJvbSk7CiAgICAgICAgcmV0dXJuIGZyb207CiAgICB9Cn07CgoKLy8gc3BlY2lhbGl6ZWQgZm9yIGN0eXBlPGNoYXI+Cl9SV1NURF9TUEVDSUFMSVpFRF9DTEFTUwpDdHlwZTxjaGFyPjo6Q3R5cGUgKHVuc2lnbmVkIHJlZiwgY2hhciB3aGl0ZSkKICAgIDogQmFzZSAodGFibGVfLCBmYWxzZSwgcmVmKSwgd3NfICh3aGl0ZSkKewogICAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSAhPSBzaXplb2YgdGFibGVfIC8gc2l6ZW9mICp0YWJsZV87ICsraSkKICAgICAgICB0YWJsZV8gW2ldID0gc3RkOjpjdHlwZV9iYXNlOjptYXNrICgpOwoKICAgIHR5cGVkZWYgdW5zaWduZWQgY2hhciBVQ2hhcjsKCiAgICB0YWJsZV8gW1VDaGFyICh3c18pXSA9IHN0ZDo6Y3R5cGVfYmFzZTo6c3BhY2U7Cn0KCgp0ZW1wbGF0ZSA8Y2xhc3MgY2hhclQsIGNsYXNzIFRyYWl0cz4Kc3RydWN0IFN0cmVhbWJ1Zjogc3RkOjpiYXNpY19zdHJlYW1idWY8Y2hhclQsIFRyYWl0cz4KewogICAgdHlwZWRlZiBzdGQ6OmJhc2ljX3N0cmVhbWJ1ZjxjaGFyVCwgVHJhaXRzPiBCYXNlOwoKICAgIGludCBuc3luY3NfOwoKICAgIFN0cmVhbWJ1ZiAoY29uc3QgY2hhclQgKmdiZWcsIGNvbnN0IGNoYXJUICpnZW5kKQogICAgICAgIDogQmFzZSAoKSwgbnN5bmNzXyAoMCkgewogICAgICAgIHRoaXMtPnNldGcgKF9SV1NURF9DT05TVF9DQVNUIChjaGFyVCosIGdiZWcpLAogICAgICAgICAgICAgICAgICAgIF9SV1NURF9DT05TVF9DQVNUIChjaGFyVCosIGdiZWcpLAogICAgICAgICAgICAgICAgICAgIF9SV1NURF9DT05TVF9DQVNUIChjaGFyVCosIGdlbmQpKTsKICAgIH0KCiAgICBjb25zdCBjaGFyVCogcHViZWJhY2sgKCkgY29uc3QgewogICAgICAgIHJldHVybiB0aGlzLT5lYmFjayAoKTsKICAgIH0KCiAgICBjb25zdCBjaGFyVCogcHViZ3B0ciAoKSBjb25zdCB7CiAgICAgICAgcmV0dXJuIHRoaXMtPmdwdHIgKCk7CiAgICB9CgogICAgY29uc3QgY2hhclQqIHB1YmVncHRyICgpIGNvbnN0IHsKICAgICAgICByZXR1cm4gdGhpcy0+ZWdwdHIgKCk7CiAgICB9CgogICAgLyogdmlydHVhbCAqLyBpbnQgc3luYyAoKSB7CiAgICAgICAgKytuc3luY3NfOwogICAgICAgIHJldHVybiBCYXNlOjpzeW5jICgpOwogICAgfQp9OwoKCnRlbXBsYXRlIDxjbGFzcyBjaGFyVCwgY2xhc3MgVHJhaXRzPgp2b2lkIHRlc3RfY3RvciAoY29uc3QgY2hhclQqLCBjb25zdCBUcmFpdHMqLAogICAgICAgICAgICAgICAgY29uc3QgY2hhciAqY25hbWUsIGNvbnN0IGNoYXIgKnRuYW1lKQp7CiAgICB0eXBlZGVmIHN0ZDo6YmFzaWNfaXN0cmVhbTxjaGFyVCwgVHJhaXRzPiAgIElzdHJlYW07CiAgICB0eXBlZGVmIHR5cGVuYW1lIElzdHJlYW06OnNlbnRyeSAgICAgICAgICAgIFNlbnRyeTsKCiAgICBtZW1mdW5faW5mbyAoX19MSU5FX18sIGNuYW1lLCB0bmFtZSwgInNlbnRyeSAoJXskSVNUUkVBTX0mLCBib29sKSIpOwoKICAgIGNvbnN0IGNoYXJUIGNidWZbXSA9IHsgJ2EnLCAnYicsICdjJywgJ2QnLCAnZScsICcgJywgJ2YnLCAnXDAnIH07CgogICAgY29uc3Qgc3RkOjppb3NfYmFzZTo6aW9zdGF0ZSBzdGF0ZXNbXSA9IHsKICAgICAgICBzdGQ6Omlvc19iYXNlOjpiYWRiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6ZW9mYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6OmZhaWxiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6Z29vZGJpdCwKICAgICAgICBzdGQ6Omlvc19iYXNlOjpiYWRiaXQgfCBzdGQ6Omlvc19iYXNlOjplb2ZiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6YmFkYml0IHwgc3RkOjppb3NfYmFzZTo6ZmFpbGJpdCwKICAgICAgICBzdGQ6Omlvc19iYXNlOjplb2ZiaXQgfCBzdGQ6Omlvc19iYXNlOjpmYWlsYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6OmJhZGJpdCB8IHN0ZDo6aW9zX2Jhc2U6OmVvZmJpdCB8IHN0ZDo6aW9zX2Jhc2U6OmZhaWxiaXQKICAgIH07CgogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgIC8vIGV4ZXJjaXNlIDI3LjYuMS4xLjIsIHAxOgogICAgLy8gICAgIC0gIGlzLmdvb2QoKSBpcyB0cnVlCiAgICAvLyAgICAgLSAgaXMudGllKCkgaXMgbm90IG51bGwKICAgIC8vICAgICA9ICB0aGUgZnVuY3Rpb24gY2FsbHMgaXMudGllKCkuZmx1c2goKQoKICAgIHVuc2lnbmVkIGl0ZXIgPSAwOyAgICAgLy8gaXRlcmF0aW9uIGNvdW50ZXIKCiAgICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBpICE9IHNpemVvZiBzdGF0ZXMgLyBzaXplb2YgKnN0YXRlczsgKytpKSB7CiAgICAgICAgZm9yICh1bnNpZ25lZCBqID0gMDsgaiAhPSAyOyArK2ogLyogbm9za2lwd3MgKi8pIHsKICAgICAgICAgICAgU3RyZWFtYnVmPGNoYXJULCBUcmFpdHM+CiAgICAgICAgICAgICAgICBzYiAoY2J1ZiwgY2J1ZiArIHNpemVvZiBjYnVmIC8gc2l6ZW9mICpjYnVmKTsKCiAgICAgICAgICAgIElzdHJlYW0gaXMgKCZzYik7CgogICAgICAgICAgICAvLyBmbHVzaCgpIGlzIGNhbGxlZCBpZmYKICAgICAgICAgICAgLy8gYWxsIG9mIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBob2xkCiAgICAgICAgICAgIGNvbnN0IGJvb2wgZmx1c2hfY2FsbGVkID0gaXMuZ29vZCAoKSAmJiAwICE9IGlzLnRpZSAoKTsKCiAgICAgICAgICAgIGNvbnN0IFNlbnRyeSBndWFyZCAoaXMsIDAgIT0gaik7CgogICAgICAgICAgICBfUldTVERfVU5VU0VEIChndWFyZCk7CgogICAgICAgICAgICByd19hc3NlcnQgKGZsdXNoX2NhbGxlZCA9PSBzYi5uc3luY3NfLCAwLCBfX0xJTkVfXywKICAgICAgICAgICAgICAgICAgICAgICAiJXUuIGJhc2ljX2lzdHJlYW08JXMsICVzPjo6c2VudHJ5OjpzZW50cnkiCiAgICAgICAgICAgICAgICAgICAgICAgIihiYXNpY19pc3RyZWFtICZpcywgYm9vbCBub3NraXB3cyA9ICVkKTsgIgogICAgICAgICAgICAgICAgICAgICAgICJleHBlY3RlZCB0byBjYWxsIGlzLmZsdXNoICgpICVkIHRpbWVzLCBnb3QgJWQiCiAgICAgICAgICAgICAgICAgICAgICAgImluaXRpYWwgaXMuc3RhdGUgKCkgPSAle0lzfSwgaXMuZmxhZ3MoKSAmICIKICAgICAgICAgICAgICAgICAgICAgICAiaW9zOjpza2lwd3MgPSAlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgaXRlciwgY25hbWUsIHRuYW1lLCAwICE9IGosIGZsdXNoX2NhbGxlZCwgc2IubnN5bmNzXywKICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZXMgW2ldLCBpcy5mbGFncyAoKSAmIHN0ZDo6aW9zX2Jhc2U6OnNraXB3cyk7CgogICAgICAgICAgICArK2l0ZXI7CiAgICAgICAgfQogICAgfQoKICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvLyBleGVyY2lzZSAyNy42LjEuMS4yLCBwMToKICAgIC8vICAgICAtICBpcy5nb29kKCkgaXMgdHJ1ZQogICAgLy8gICAgIC0gIG5vc2tpcHdzIGlzIHplcm8KICAgIC8vICAgICAtICBpcy5mbGFncygpICYgaW9zX2Jhc2U6OnNraXB3cwogICAgLy8gICAgID0gIHRoZSBmdW5jdGlvbiBleHRyYWN0cyBhbmQgZGlzY2FyZHMgZWFjaCBjaGFyYWN0ZXIgYXMgbG9uZwogICAgLy8gICAgICAgIGFzIHRoZSBuZXh0IGF2YWlsYWJsZSBpbnB1dCBjaGFyYWN0ZXIgYyBpcyBhIHdoaXRlc3BhY2UKICAgIC8vICAgICAgICBjaGFyYWN0ZXIuCgogICAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSAhPSBzaXplb2Ygc3RhdGVzIC8gc2l6ZW9mICpzdGF0ZXM7ICsraSkgewogICAgICAgIGZvciAodW5zaWduZWQgaiA9IDA7IGogIT0gMjsgKytqIC8qIG5vc2tpcHdzICovKSB7CiAgICAgICAgICAgIGZvciAodW5zaWduZWQgayA9IDA7IGsgIT0gMjsgKytrIC8qIGlvc19iYXNlOjpza2lwd3MgKi8pIHsKICAgICAgICAgICAgICAgIGZvciAoY2hhclQgd2MgPSBjaGFyVCAoJ2EnKTsgd2MgIT0gY2hhclQgKCdjJyk7ICsrd2MpIHsKCiAgICAgICAgICAgICAgICAgICAgY29uc3QgQ3R5cGU8Y2hhclQ+IGN0cCAoMSwgd2MpOwoKICAgICAgICAgICAgICAgICAgICBTdHJlYW1idWY8Y2hhclQsIFRyYWl0cz4KICAgICAgICAgICAgICAgICAgICAgICAgc2IgKGNidWYsIGNidWYgKyBzaXplb2YgY2J1ZiAvIHNpemVvZiAqY2J1Zik7CgogICAgICAgICAgICAgICAgICAgIElzdHJlYW0gaXMgKCZzYik7CgogICAgICAgICAgICAgICAgICAgIGlzLnNldHN0YXRlIChzdGF0ZXMgW2ldKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGspCiAgICAgICAgICAgICAgICAgICAgICAgIGlzLnNldGYgKHN0ZDo6aW9zX2Jhc2U6OnNraXB3cyk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBpcy51bnNldGYgKHN0ZDo6aW9zX2Jhc2U6OnNraXB3cyk7CgogICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0ZDo6bG9jYWxlIGxvYyA9IAogICAgICAgICAgICAgICAgICAgICAgICBpcy5pbWJ1ZSAoc3RkOjpsb2NhbGUgKGlzLmdldGxvYyAoKSwgJmN0cCkpOwoKICAgICAgICAgICAgICAgICAgICAvLyBpbWJ1ZSB0aGUgcHJldmlvdXMgbG9jYWxlIGludG8gdGhlIHN0cmVhbQogICAgICAgICAgICAgICAgICAgIC8vIGJ1ZmZlciB0byB2ZXJpZnkgdGhhdCB0aGUgc2VudHJ5IGN0b3IgdXNlcwogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBsb2NhbGUgaW1idWVkIGluIHRoZSBzdHJlYW0gb2JqZWN0IGFuZAogICAgICAgICAgICAgICAgICAgIC8vIG5vdCB0aGUgb25lIGluIHRoZSBzdHJlYW0gYnVmZmVyCiAgICAgICAgICAgICAgICAgICAgc2IucHViaW1idWUgKGxvYyk7CgogICAgICAgICAgICAgICAgICAgIC8vIGEgd2hpdGVzcGFjZSBjaGFyYWN0ZXIgaXMgZXh0cmFjdGVkIGlmZgogICAgICAgICAgICAgICAgICAgIC8vIGFsbCBvZiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgaG9sZAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGJvb2wgZXh0cmFjdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzLmdvb2QgKCkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgMCA9PSBqCiAgICAgICAgICAgICAgICAgICAgICAgICYmIGlzLmZsYWdzICgpICYgc3RkOjppb3NfYmFzZTo6c2tpcHdzCiAgICAgICAgICAgICAgICAgICAgICAgICYmIGNidWYgWzBdID09IHdjOwoKICAgICAgICAgICAgICAgICAgICBjb25zdCBTZW50cnkgZ3VhcmQgKGlzLCAwICE9IGopOwoKICAgICAgICAgICAgICAgICAgICBfUldTVERfVU5VU0VEIChndWFyZCk7CgogICAgICAgICAgICAgICAgICAgIHJ3X2Fzc2VydCAoY2J1ZiArIGV4dHJhY3QgPT0gc2IucHViZ3B0ciAoKSwgMCwgX19MSU5FX18sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiV1LiAleyRTRU5UUll9OjpzZW50cnkiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCV7JElTVFJFQU19ICZpcywgYm9vbCBub3NraXB3cyAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPSAlYik7IGV4cGVjdGVkIHRvIGV4dHJhY3QgJWQgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndoaXRlc3BhY2UgY2hhcnMgKCclYycpIGZyb20gJXsqQWN9LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXh0cmFjdGVkICV1OyBpbml0aWFsIGlzLnN0YXRlICgpID0gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiV7SXN9LCBpcy5mbGFncygpICYgaW9zOjpza2lwd3MgPSAlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyLCBqLCBleHRyYWN0ICsgMCwgY2hhciAod2MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IChzaXplb2YgKCpjYnVmKSksIGNidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYi5wdWJncHRyICgpIC0gc2IucHViZWJhY2sgKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZXMgW2ldLCBrKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gdmVyaWZ5IHRoYXQgdGhlIGN0b3IgZG9lc24ndCBhZmZlY3QgZ2NvdW50KCkKICAgICAgICAgICAgICAgICAgICByd19hc3NlcnQgKDAgPT0gaXMuZ2NvdW50ICgpLCAwLCBfX0xJTkVfXywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXUuICV7JFNFTlRSWX06OnNlbnRyeSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoJXskSVNUUkVBTX0gJmlzID0gJXsqQWN9LCBib29sIG5vc2tpcHdzICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI9ICViKTsgY2hhbmdlZCBpcy5nY291bnQoKSBmcm9tIDAgdG8gJWkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciwgaW50IChzaXplb2YgKCpjYnVmKSksIGNidWYsIGosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcy5nY291bnQgKCkpOwoKICAgICAgICAgICAgICAgICAgICArK2l0ZXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnRlbXBsYXRlIDxjbGFzcyBjaGFyVCwgY2xhc3MgVHJhaXRzPgp2b2lkIHRlc3Rfb2sgKGNvbnN0IGNoYXJUKiwgY29uc3QgVHJhaXRzKiwKICAgICAgICAgICAgICBjb25zdCBjaGFyICpjbmFtZSwgY29uc3QgY2hhciAqdG5hbWUpCnsKICAgIHR5cGVkZWYgc3RkOjpiYXNpY19pc3RyZWFtPGNoYXJULCBUcmFpdHM+ICAgSXN0cmVhbTsKICAgIHR5cGVkZWYgdHlwZW5hbWUgSXN0cmVhbTo6c2VudHJ5ICAgICAgICAgICAgU2VudHJ5OwoKICAgIG1lbWZ1bl9pbmZvIChfX0xJTkVfXywgY25hbWUsIHRuYW1lLCAib3BlcmF0b3IgYm9vbCAoKSBjb25zdCIpOwoKICAgIGNvbnN0IGNoYXJUIGNidWZbXSA9IHsgJ2EnLCAnYicsICdjJywgJ2QnLCAnZScsICcgJywgJ2YnLCAnXDAnIH07CgogICAgY29uc3Qgc3RkOjppb3NfYmFzZTo6aW9zdGF0ZSBzdGF0ZXNbXSA9IHsKICAgICAgICBzdGQ6Omlvc19iYXNlOjpiYWRiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6ZW9mYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6OmZhaWxiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6Z29vZGJpdCwKICAgICAgICBzdGQ6Omlvc19iYXNlOjpiYWRiaXQgfCBzdGQ6Omlvc19iYXNlOjplb2ZiaXQsCiAgICAgICAgc3RkOjppb3NfYmFzZTo6YmFkYml0IHwgc3RkOjppb3NfYmFzZTo6ZmFpbGJpdCwKICAgICAgICBzdGQ6Omlvc19iYXNlOjplb2ZiaXQgfCBzdGQ6Omlvc19iYXNlOjpmYWlsYml0LAogICAgICAgIHN0ZDo6aW9zX2Jhc2U6OmJhZGJpdCB8IHN0ZDo6aW9zX2Jhc2U6OmVvZmJpdCB8IHN0ZDo6aW9zX2Jhc2U6OmZhaWxiaXQKICAgIH07CgogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgIC8vIGV4ZXJjaXNlIDI3LjYuMS4xLjIsIHA1OgogICAgLy8gICAgIC0gIGlzLmdvb2QoKSBpcyB0cnVlCiAgICAvLyAgICAgLSAgbm9za2lwd3MgaXMgemVybwogICAgLy8gICAgIC0gIGlzLmZsYWdzKCkgJiBpb3NfYmFzZTo6c2tpcHdzCiAgICAvLyAgICAgLSAgdGhlIGZ1bmN0aW9uIGV4dHJhY3RzIGFuZCBkaXNjYXJkcyBlYWNoIGNoYXJhY3RlciBhcyBsb25nCiAgICAvLyAgICAgICAgYXMgdGhlIG5leHQgYXZhaWxhYmxlIGlucHV0IGNoYXJhY3RlciBjIGlzIGEgd2hpdGVzcGFjZQogICAgLy8gICAgICAgIGNoYXJhY3RlcgogICAgLy8gICAgID0gIGlmLCBhZnRlciBhbnkgcHJlcGFyYXRpb24gaXMgY29tcGxldGVkLCBpcy5nb29kKCkgaXMgdHJ1ZSwKICAgIC8vICAgICAgICBva18gIT0gZmFsc2Ugb3RoZXJ3aXNlLCBva18gPT0gZmFsc2UuCgogICAgdW5zaWduZWQgaXRlciA9IDA7ICAgICAvLyBpdGVyYXRpb24gY291bnRlcgoKICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgIT0gc2l6ZW9mIHN0YXRlcyAvIHNpemVvZiAqc3RhdGVzOyArK2kpIHsKICAgICAgICBmb3IgKHVuc2lnbmVkIGogPSAwOyBqICE9IDI7ICsraiAvKiBub3NraXB3cyAqLykgewogICAgICAgICAgICBmb3IgKHVuc2lnbmVkIGsgPSAwOyBrICE9IDI7ICsrayAvKiBpb3NfYmFzZTo6c2tpcHdzICovKSB7CiAgICAgICAgICAgICAgICBmb3IgKGNoYXJUIHdjID0gY2hhclQgKCdhJyk7IHdjICE9IGNoYXJUICgnYycpOyArK3djKSB7CgogICAgICAgICAgICAgICAgICAgIGNvbnN0IEN0eXBlPGNoYXJUPiBjdHAgKDEsIHdjKTsKCiAgICAgICAgICAgICAgICAgICAgU3RyZWFtYnVmPGNoYXJULCBUcmFpdHM+CiAgICAgICAgICAgICAgICAgICAgICAgIHNiIChjYnVmLCBjYnVmICsgc2l6ZW9mIGNidWYgLyBzaXplb2YgKmNidWYpOwoKICAgICAgICAgICAgICAgICAgICBJc3RyZWFtIGlzICgmc2IpOwoKICAgICAgICAgICAgICAgICAgICBpcy5zZXRzdGF0ZSAoc3RhdGVzIFtpXSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChrKQogICAgICAgICAgICAgICAgICAgICAgICBpcy5zZXRmIChzdGQ6Omlvc19iYXNlOjpza2lwd3MpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgaXMudW5zZXRmIChzdGQ6Omlvc19iYXNlOjpza2lwd3MpOwoKICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OmxvY2FsZSBsb2MgPSAKICAgICAgICAgICAgICAgICAgICAgICAgaXMuaW1idWUgKHN0ZDo6bG9jYWxlIChpcy5nZXRsb2MgKCksICZjdHApKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gaW1idWUgdGhlIHByZXZpb3VzIGxvY2FsZSBpbnRvIHRoZSBzdHJlYW0KICAgICAgICAgICAgICAgICAgICAvLyBidWZmZXIgdG8gdmVyaWZ5IHRoYXQgdGhlIHNlbnRyeSBjdG9yIHVzZXMKICAgICAgICAgICAgICAgICAgICAvLyB0aGUgbG9jYWxlIGltYnVlZCBpbiB0aGUgc3RyZWFtIG9iamVjdCBhbmQKICAgICAgICAgICAgICAgICAgICAvLyBub3QgdGhlIG9uZSBpbiB0aGUgc3RyZWFtIGJ1ZmZlcgogICAgICAgICAgICAgICAgICAgIHNiLnB1YmltYnVlIChsb2MpOwoKICAgICAgICAgICAgICAgICAgICBjb25zdCBTZW50cnkgZ3VhcmQgKGlzLCAwICE9IGopOwoKICAgICAgICAgICAgICAgICAgICBfUldTVERfVU5VU0VEIChndWFyZCk7CgogICAgICAgICAgICAgICAgICAgIC8vIHZlcmlmeSB0aGF0IGJvdGggYXJlIGVpdGhlciBmYWxzZSBvciB0cnVlCiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm9vbCBzdWNjZXNzID0gIWlzLmdvb2QgKCkgPT0gIWd1YXJkOwoKICAgICAgICAgICAgICAgICAgICByd19hc3NlcnQgKHN1Y2Nlc3MsIDAsIF9fTElORV9fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiV1LiAleyRTRU5UUll9IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIigleyRJU1RSRUFNfSAmaXMsIGJvb2wgbm9za2lwd3MgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIj0gJWQpLm9wZXJhdG9yIGJvb2woKSA9PSAlZDsgaW5pdGlhbCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXMuc3RhdGUoKSA9ICV7SXN9LCBpcy5mbGFncygpICYgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImlvczo6c2tpcHdzID0gJWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciwgaiwgaXMuZ29vZCAoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlcyBbaV0sIGspOwoKICAgICAgICAgICAgICAgICAgICArK2l0ZXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBpbnQgb3B0X2NoYXI7CnN0YXRpYyBpbnQgb3B0X3djaGFyOwpzdGF0aWMgaW50IG9wdF9jaGFyX3RyYWl0czsKc3RhdGljIGludCBvcHRfdXNlcl90cmFpdHM7CgoKc3RhdGljIGludApydW5fdGVzdCAoaW50LCBjaGFyKiopCnsKI2RlZmluZSBURVNUKHdoYXQsIGNoYXJULCBUcmFpdHMpIFwKICAgIHRlc3RfICMjIHdoYXQgKChjaGFyVCopMCwgKFRyYWl0cyopMCwgI2NoYXJULCAjVHJhaXRzKQoKICAgIHVzaW5nIG5hbWVzcGFjZSBzdGQ7CgogICAgaWYgKHJ3X25vdGUgKDAgPD0gb3B0X2NoYXIgJiYgMCA8PSBvcHRfY2hhcl90cmFpdHMsIDAsIF9fTElORV9fLAogICAgICAgICAgICAgICAgICJpc3RyZWFtOjpzZW50cnkgdGVzdHMgZGlzYWJsZWQiKSkgewogICAgICAgIFRFU1QgKGN0b3IsIGNoYXIsIGNoYXJfdHJhaXRzPGNoYXI+KTsKICAgICAgICBURVNUIChvaywgY2hhciwgY2hhcl90cmFpdHM8Y2hhcj4pOwogICAgfQoKICAgIGlmIChyd19ub3RlICgwIDw9IG9wdF9jaGFyICYmIDAgPD0gb3B0X3VzZXJfdHJhaXRzLCAwLCBfX0xJTkVfXywKICAgICAgICAgICAgICAgICAiYmFzaWNfaXN0cmVhbTxjaGFyLCBVc2VyVHJhaXRzPGNoYXI+OjpzZW50cnkgIgogICAgICAgICAgICAgICAgICJ0ZXN0cyBkaXNhYmxlZCIpKSB7CiAgICAgICAgVEVTVCAoY3RvciwgY2hhciwgVXNlclRyYWl0czxjaGFyPik7CiAgICAgICAgVEVTVCAob2ssIGNoYXIsIFVzZXJUcmFpdHM8Y2hhcj4pOwogICAgfQoKI2lmbmRlZiBfUldTVERfTk9fV0NIQVJfVAoKICAgIGlmIChyd19ub3RlICgwIDw9IG9wdF93Y2hhciAmJiAwIDw9IG9wdF9jaGFyX3RyYWl0cywgMCwgX19MSU5FX18sCiAgICAgICAgICAgICAgICAgIndpc3RyZWFtOjpzZW50cnkgdGVzdHMgZGlzYWJsZWQiKSkgewogICAgICAgIFRFU1QgKGN0b3IsIHdjaGFyX3QsIGNoYXJfdHJhaXRzPHdjaGFyX3Q+KTsKICAgICAgICBURVNUIChvaywgd2NoYXJfdCwgY2hhcl90cmFpdHM8d2NoYXJfdD4pOwogICAgfQoKICAgIGlmIChyd19ub3RlICgwIDw9IG9wdF93Y2hhciAmJiAwIDw9IG9wdF91c2VyX3RyYWl0cywgMCwgX19MSU5FX18sCiAgICAgICAgICAgICAgICAgImJhc2ljX2lzdHJlYW08d2NoYXJfdCwgVXNlclRyYWl0czx3Y2hhcl90Pjo6c2VudHJ5ICIKICAgICAgICAgICAgICAgICAidGVzdHMgZGlzYWJsZWQiKSkgewogICAgICAgIFRFU1QgKGN0b3IsIHdjaGFyX3QsIFVzZXJUcmFpdHM8d2NoYXJfdD4pOwogICAgICAgIFRFU1QgKG9rLCB3Y2hhcl90LCBVc2VyVHJhaXRzPHdjaGFyX3Q+KTsKICAgIH0KCiNlbmRpZiAgIC8vIF9SV1NURF9OT19XQ0hBUl9UCgogICAgcmV0dXJuIDA7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgppbnQgbWFpbiAoaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKewogICAgcmV0dXJuIHJ3X3Rlc3QgKGFyZ2MsIGFyZ3YsIF9fRklMRV9fLAogICAgICAgICAgICAgICAgICAgICJpc3RyZWFtLnNlbnRyeSIsCiAgICAgICAgICAgICAgICAgICAgMCAvKiBubyBjb21tZW50ICovLAogICAgICAgICAgICAgICAgICAgIHJ1bl90ZXN0LAogICAgICAgICAgICAgICAgICAgICJ8LWNoYXJ+ICIKICAgICAgICAgICAgICAgICAgICAifC13Y2hhcl90fiAiCiAgICAgICAgICAgICAgICAgICAgInwtY2hhcl90cmFpdHN+ICIKICAgICAgICAgICAgICAgICAgICAifC1Vc2VyVHJhaXRzfiAiLAogICAgICAgICAgICAgICAgICAgICZvcHRfY2hhciwKICAgICAgICAgICAgICAgICAgICAmb3B0X3djaGFyLAogICAgICAgICAgICAgICAgICAgICZvcHRfY2hhcl90cmFpdHMsCiAgICAgICAgICAgICAgICAgICAgJm9wdF91c2VyX3RyYWl0cywKICAgICAgICAgICAgICAgICAgICAodm9pZCopMCAgIC8qIHNlbnRpbmVsICovKTsKfQo=