LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBDb3B5cmlnaHQgKGMpIDIwMjEgQ2VudHJhbGVTdXBlbGVjLCBDRUEtTElTVAoqCiogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwoqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wCiogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKiBodHRwczovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wLwoqCiogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjAKKgoqIENvbnRyaWJ1dG9yczoKKiBFcndhbiBNYWjpIChDZW50cmFsZVN1cGVsZWMpIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp1c2UgY3JhdGU6OmNvcmU6OmNvbnRleHQ6OmdlbmVyYWw6OkdlbmVyYWxDb250ZXh0Owp1c2UgY3JhdGU6OmNvcmU6OmNvbnRleHQ6OmV4ZWN1dGlvbjo6RXhlY3V0aW9uQ29udGV4dDsKCnVzZSBjcmF0ZTo6Y29yZTo6c3ludGF4OjpkYXRhOjp2YXJfcmVmOjpWYXJpYWJsZVJlZmVyZW5jZTsKdXNlIGNyYXRlOjpjb3JlOjpzeW50YXg6OmRhdGE6OnRkX3R5cGU6OlREX0RhdGFUeXBlOwp1c2UgY3JhdGU6OmNvcmU6OnN5bnRheDo6ZGF0YTo6Z2VuZXJpYzo6VERfR2VuZXJpYzsKdXNlIGNyYXRlOjpjb3JlOjpzeW50YXg6OmRhdGE6OmJ1aWx0aW46OmJvb2w6Oio7CnVzZSBjcmF0ZTo6Y29yZTo6c3ludGF4OjpkYXRhOjpidWlsdGluOjpudW1iZXI6Oio7CnVzZSBjcmF0ZTo6Y29yZTo6c3ludGF4OjpkYXRhOjpidWlsdGluOjppbnRlZ2VyOjpURF9JbnRlZ2VyOwp1c2UgY3JhdGU6OmNvcmU6OnN5bnRheDo6ZGF0YTo6YnVpbHRpbjo6ZmxvYXQ6OlREX0Zsb2F0Owp1c2UgY3JhdGU6OmNvcmU6OnN5bnRheDo6ZGF0YTo6YnVpbHRpbjo6c3RyaW5nOjpURF9TdHJpbmc7Cgp1c2UgY3JhdGU6OmRpdmVyc2l0eTo6KjsKdXNlIGNyYXRlOjpkaXZlcnNpdHk6OmV4cHJlc3Npb246OkV4cHJlc3Npb25BbHQ7Cgp1c2UgY3JhdGU6OmNvcmU6OmVycm9yOjpIaWJvdUNvcmVFcnJvcjsKCgpmbiBzeW1ib2xfcmVmZXJlbmNlX2Zyb21fZ3JwYyhnZW5fY3R4IDogJkdlbmVyYWxDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVfY3R4IDogJkV4ZWN1dGlvbkNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bWJvbF9mcW4gOiAmU3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZF90eXBlIDogJlREX0RhdGFUeXBlKSAtPiBSZXN1bHQ8VERfR2VuZXJpYyxIaWJvdUNvcmVFcnJvcj4gewogICAgbWF0Y2ggZXhlX2N0eC5nZXRfc3lfdHlwZV9mcm9tX2ZxbiggJnN5bWJvbF9mcW4pIHsKICAgICAgICBFcnIoZSkgPT4gewogICAgICAgICAgICByZXR1cm4gRXJyKGUpOwogICAgICAgIH0sCiAgICAgICAgT2soIHN5X3R5cGUgKSA9PiB7CiAgICAgICAgICAgIGlmICZzeV90eXBlICE9IGV4cGVjdGVkX3R5cGUgewogICAgICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dChzeW1ib2xfZnFuLmNsb25lKCksIHN5X3R5cGUuY2xvbmUoKSwgZXhwZWN0ZWRfdHlwZS5hc194bGlhX3N0cigpICkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1hdGNoIHN5X3R5cGUgewogICAgICAgICAgICAgICAgVERfRGF0YVR5cGU6OlN0cmluZyA9PiB7CiAgICAgICAgICAgICAgICAgICAgbGV0IHRkX3N0ciA9IFREX1N0cmluZzo6UmVmZXJlbmNlKCBWYXJpYWJsZVJlZmVyZW5jZTo6U1lNQk9MKCBleGVfY3R4LmdldF9zeV9pZF9mcm9tX2Zxbigmc3ltYm9sX2ZxbikudW53cmFwKCkgKSApOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6U3RyaW5nKHRkX3N0cikgKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBURF9EYXRhVHlwZTo6SW50ZWdlciA9PiB7CiAgICAgICAgICAgICAgICAgICAgbGV0IHRkX2ludCA9IFREX0ludGVnZXI6OlJlZmVyZW5jZSggVmFyaWFibGVSZWZlcmVuY2U6OlNZTUJPTCggZXhlX2N0eC5nZXRfc3lfaWRfZnJvbV9mcW4oJnN5bWJvbF9mcW4pLnVud3JhcCgpICkgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2soIFREX0dlbmVyaWM6OkludGVnZXIodGRfaW50KSApOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFREX0RhdGFUeXBlOjpGbG9hdCA9PiB7CiAgICAgICAgICAgICAgICAgICAgbGV0IHRkX2Zsb2F0ID0gVERfRmxvYXQ6OlJlZmVyZW5jZSggVmFyaWFibGVSZWZlcmVuY2U6OlNZTUJPTCggZXhlX2N0eC5nZXRfc3lfaWRfZnJvbV9mcW4oJnN5bWJvbF9mcW4pLnVud3JhcCgpICkgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2soIFREX0dlbmVyaWM6OkZsb2F0KHRkX2Zsb2F0KSApOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFREX0RhdGFUeXBlOjpCb29sID0+IHsKICAgICAgICAgICAgICAgICAgICBsZXQgdGRfYm9vbCA9IFREX0Jvb2w6OlJlZmVyZW5jZSggVmFyaWFibGVSZWZlcmVuY2U6OlNZTUJPTCggZXhlX2N0eC5nZXRfc3lfaWRfZnJvbV9mcW4oJnN5bWJvbF9mcW4pLnVud3JhcCgpICkgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2soIFREX0dlbmVyaWM6OkJvb2wodGRfYm9vbCkgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKZm4gZ2V0X3N1Yl9leHByZXNzaW9ucyhnZW5fY3R4IDogJkdlbmVyYWxDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgIGV4ZV9jdHggOiAmRXhlY3V0aW9uQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gOiAmT3BlcmF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkX3R5cGUgOiAmVERfRGF0YVR5cGUpIC0+IFJlc3VsdDxWZWM8IFREX0dlbmVyaWMgPixIaWJvdUNvcmVFcnJvcj4gewogICAgbGV0IG11dCBzdWJfZXhwcmVzc2lvbnMgOiBWZWM8IFREX0dlbmVyaWMgPiA9IFZlYzo6bmV3KCk7CiAgICBmb3IgZXhwcmVzc2lvbiBpbiAmb3BlcmF0aW9uLm9wZXJhbmQgewogICAgICAgIG1hdGNoIGV4cHJlc3Npb25fZnJvbV9ncnBjKGdlbl9jdHgsZXhlX2N0eCxleHByZXNzaW9uLGV4cGVjdGVkX3R5cGUpIHsKICAgICAgICAgICAgRXJyKGUpID0+IHsKICAgICAgICAgICAgICAgIHJldHVybiBFcnIoZSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIE9rKCB0ZF9nZW4gKSA9PiB7CiAgICAgICAgICAgICAgICBzdWJfZXhwcmVzc2lvbnMucHVzaCggdGRfZ2VuICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gT2soIHN1Yl9leHByZXNzaW9ucyApOwp9CgpmbiBvcGVyYXRpb25fZnJvbV9ncnBjKGdlbl9jdHggOiAmR2VuZXJhbENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgZXhlX2N0eCA6ICZFeGVjdXRpb25Db250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbiA6ICZPcGVyYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWRfdHlwZSA6ICZURF9EYXRhVHlwZSkgLT4gUmVzdWx0PFREX0dlbmVyaWMsSGlib3VDb3JlRXJyb3I+IHsKICAgIGlmIG9wZXJhdGlvbi5vcGVyYXRvcl9raW5kID09ICggT3BlcmF0b3JLaW5kOjpBZGQgYXMgaTMyICkgewogICAgICAgIG1hdGNoIGdldF9zdWJfZXhwcmVzc2lvbnMoZ2VuX2N0eCxleGVfY3R4LG9wZXJhdGlvbixleHBlY3RlZF90eXBlKSB7CiAgICAgICAgICAgIEVycihlKSA9PiB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXJyKGUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBPayggbXV0IHN1Yl9leHByZXNzaW9ucyApID0+IHsKICAgICAgICAgICAgICAgIG1hdGNoIGV4cGVjdGVkX3R5cGUgewogICAgICAgICAgICAgICAgICAgIFREX0RhdGFUeXBlOjpJbnRlZ2VyID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG11dCBhZGRfdmVjIDogVmVjPChBUklUSF9BRERfU0lHTixURF9JbnRlZ2VyKT4gPSBWZWM6Om5ldygpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3Igc3ViX2V4cHIgaW4gc3ViX2V4cHJlc3Npb25zIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoIHN1Yl9leHByIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBURF9HZW5lcmljOjpJbnRlZ2VyKHRkX2ludCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRfdmVjLnB1c2goIChBUklUSF9BRERfU0lHTjo6UGx1cywgdGRfaW50KSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXyA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnIoIEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXRPcGVyYXRpb24ob3BlcmF0aW9uLmNsb25lKCkpICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6SW50ZWdlciggVERfSW50ZWdlcjo6QWRkKGFkZF92ZWMpICkgKTsKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIFREX0RhdGFUeXBlOjpGbG9hdCA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBtdXQgYWRkX3ZlYyA6IFZlYzwoQVJJVEhfQUREX1NJR04sVERfRmxvYXQpPiA9IFZlYzo6bmV3KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciBzdWJfZXhwciBpbiBzdWJfZXhwcmVzc2lvbnMgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggc3ViX2V4cHIgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFREX0dlbmVyaWM6OkZsb2F0KHRkX2Zsb2F0KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZF92ZWMucHVzaCggKEFSSVRIX0FERF9TSUdOOjpQbHVzLCB0ZF9mbG9hdCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2soIFREX0dlbmVyaWM6OkZsb2F0KCBURF9GbG9hdDo6QWRkKGFkZF92ZWMpICkgKTsKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBpZiBvcGVyYXRpb24ub3BlcmF0b3Jfa2luZCA9PSAoIE9wZXJhdG9yS2luZDo6TWludXMgYXMgaTMyICkgewogICAgICAgIG1hdGNoIGdldF9zdWJfZXhwcmVzc2lvbnMoZ2VuX2N0eCxleGVfY3R4LG9wZXJhdGlvbixleHBlY3RlZF90eXBlKSB7CiAgICAgICAgICAgIEVycihlKSA9PiB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXJyKGUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBPayggbXV0IHN1Yl9leHByZXNzaW9ucyApID0+IHsKICAgICAgICBtYXRjaCBleHBlY3RlZF90eXBlIHsKICAgICAgICAgICAgVERfRGF0YVR5cGU6OkludGVnZXIgPT4gewogICAgICAgICAgICAgICAgbGV0IG11dCBhZGRfdmVjIDogVmVjPChBUklUSF9BRERfU0lHTixURF9JbnRlZ2VyKT4gPSBWZWM6Om5ldygpOwogICAgICAgICAgICAgICAgbGV0IG11dCBmaXJzdCA6IGJvb2wgPSB0cnVlOwogICAgICAgICAgICAgICAgZm9yIHN1Yl9leHByIGluIHN1Yl9leHByZXNzaW9ucyB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggc3ViX2V4cHIgewogICAgICAgICAgICAgICAgICAgICAgICBURF9HZW5lcmljOjpJbnRlZ2VyKHRkX2ludCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZmlyc3QgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZF92ZWMucHVzaCggKEFSSVRIX0FERF9TSUdOOjpQbHVzLCB0ZF9pbnQpICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkX3ZlYy5wdXNoKCAoQVJJVEhfQUREX1NJR046Ok1pbnVzLCB0ZF9pbnQpICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6SW50ZWdlciggVERfSW50ZWdlcjo6QWRkKGFkZF92ZWMpICkgKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgVERfRGF0YVR5cGU6OkZsb2F0ID0+IHsKICAgICAgICAgICAgICAgIGxldCBtdXQgYWRkX3ZlYyA6IFZlYzwoQVJJVEhfQUREX1NJR04sVERfRmxvYXQpPiA9IFZlYzo6bmV3KCk7CiAgICAgICAgICAgICAgICBsZXQgbXV0IGZpcnN0IDogYm9vbCA9IHRydWU7CiAgICAgICAgICAgICAgICBmb3Igc3ViX2V4cHIgaW4gc3ViX2V4cHJlc3Npb25zIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaCBzdWJfZXhwciB7CiAgICAgICAgICAgICAgICAgICAgICAgIFREX0dlbmVyaWM6OkZsb2F0KHRkX2Zsb2F0KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBmaXJzdCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkX3ZlYy5wdXNoKCAoQVJJVEhfQUREX1NJR046OlBsdXMsIHRkX2Zsb2F0KSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZF92ZWMucHVzaCggKEFSSVRIX0FERF9TSUdOOjpNaW51cywgdGRfZmxvYXQpICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6RmxvYXQoIFREX0Zsb2F0OjpBZGQoYWRkX3ZlYykgKSApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfID0+IHsKICAgICAgICAgICAgICAgIHJldHVybiBFcnIoIEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXRPcGVyYXRpb24ob3BlcmF0aW9uLmNsb25lKCkpICk7CiAgICAgICAgICAgIH0KICAgICAgICB9fX0KICAgIH0gZWxzZSBpZiBvcGVyYXRpb24ub3BlcmF0b3Jfa2luZCA9PSAoIE9wZXJhdG9yS2luZDo6VW1pbnVzIGFzIGkzMiApIHsKICAgICAgICBtYXRjaCBnZXRfc3ViX2V4cHJlc3Npb25zKGdlbl9jdHgsZXhlX2N0eCxvcGVyYXRpb24sZXhwZWN0ZWRfdHlwZSkgewogICAgICAgICAgICBFcnIoZSkgPT4gewogICAgICAgICAgICAgICAgcmV0dXJuIEVycihlKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgT2soIG11dCBzdWJfZXhwcmVzc2lvbnMgKSA9PiB7CiAgICAgICAgICAgICAgICBtYXRjaCBleHBlY3RlZF90eXBlIHsKICAgICAgICAgICAgICAgICAgICBURF9EYXRhVHlwZTo6SW50ZWdlciA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHN1Yl9leHByZXNzaW9ucy5sZW4oKSAhPSAxIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnIoSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRkX2dlbiA9IHN1Yl9leHByZXNzaW9ucy5yZW1vdmUoMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCB0ZF9nZW4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFREX0dlbmVyaWM6OkludGVnZXIodGRfaW50KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPayhURF9HZW5lcmljOjpJbnRlZ2VyKFREX0ludGVnZXI6Ok1pbnVzKEJveDo6bmV3KHRkX2ludCkpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVycihIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBURF9EYXRhVHlwZTo6RmxvYXQgPT4gewogICAgICAgICAgICAgICAgICAgICAgICBpZiBzdWJfZXhwcmVzc2lvbnMubGVuKCkgIT0gMSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXRPcGVyYXRpb24ob3BlcmF0aW9uLmNsb25lKCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCB0ZF9nZW4gPSBzdWJfZXhwcmVzc2lvbnMucmVtb3ZlKDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggdGRfZ2VuIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBURF9HZW5lcmljOjpGbG9hdCh0ZF9mbG9hdCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2soVERfR2VuZXJpYzo6RmxvYXQoVERfRmxvYXQ6Ok1pbnVzKEJveDo6bmV3KHRkX2Zsb2F0KSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXRPcGVyYXRpb24ob3BlcmF0aW9uLmNsb25lKCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXRPcGVyYXRpb24ob3BlcmF0aW9uLmNsb25lKCkpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH19CiAgICB9IGVsc2UgaWYgb3BlcmF0aW9uLm9wZXJhdG9yX2tpbmQgPT0gKCBPcGVyYXRvcktpbmQ6Ok11bHQgYXMgaTMyICkgewogICAgICAgIG1hdGNoIGdldF9zdWJfZXhwcmVzc2lvbnMoZ2VuX2N0eCxleGVfY3R4LG9wZXJhdGlvbixleHBlY3RlZF90eXBlKSB7CiAgICAgICAgICAgIEVycihlKSA9PiB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXJyKGUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBPayggbXV0IHN1Yl9leHByZXNzaW9ucyApID0+IHsKICAgICAgICBtYXRjaCBleHBlY3RlZF90eXBlIHsKICAgICAgICAgICAgVERfRGF0YVR5cGU6OkludGVnZXIgPT4gewogICAgICAgICAgICAgICAgbGV0IG11dCBmYWN0b3JfdmVjIDogVmVjPChBUklUSF9GQUNUT1JfU0lHTixURF9JbnRlZ2VyKT4gPSBWZWM6Om5ldygpOwogICAgICAgICAgICAgICAgZm9yIHN1Yl9leHByIGluIHN1Yl9leHByZXNzaW9ucyB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggc3ViX2V4cHIgewogICAgICAgICAgICAgICAgICAgICAgICBURF9HZW5lcmljOjpJbnRlZ2VyKHRkX2ludCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9yX3ZlYy5wdXNoKCAoQVJJVEhfRkFDVE9SX1NJR046Ok11bHQsIHRkX2ludCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgXyA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIE9rKCBURF9HZW5lcmljOjpJbnRlZ2VyKCBURF9JbnRlZ2VyOjpGYWN0b3IoZmFjdG9yX3ZlYykgKSApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBURF9EYXRhVHlwZTo6RmxvYXQgPT4gewogICAgICAgICAgICAgICAgbGV0IG11dCBmYWN0b3JfdmVjIDogVmVjPChBUklUSF9GQUNUT1JfU0lHTixURF9GbG9hdCk+ID0gVmVjOjpuZXcoKTsKICAgICAgICAgICAgICAgIGZvciBzdWJfZXhwciBpbiBzdWJfZXhwcmVzc2lvbnMgewogICAgICAgICAgICAgICAgICAgIG1hdGNoIHN1Yl9leHByIHsKICAgICAgICAgICAgICAgICAgICAgICAgVERfR2VuZXJpYzo6RmxvYXQodGRfZmxvYXQpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY3Rvcl92ZWMucHVzaCggKEFSSVRIX0ZBQ1RPUl9TSUdOOjpNdWx0LCB0ZF9mbG9hdCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgXyA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIE9rKCBURF9HZW5lcmljOjpGbG9hdCggVERfRmxvYXQ6OkZhY3RvcihmYWN0b3JfdmVjKSApICk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgICAgICAgICAgfQogICAgICAgIH19fQogICAgfSBlbHNlIGlmIG9wZXJhdGlvbi5vcGVyYXRvcl9raW5kID09ICggT3BlcmF0b3JLaW5kOjpEaXYgYXMgaTMyICkgewogICAgICAgIG1hdGNoIGdldF9zdWJfZXhwcmVzc2lvbnMoZ2VuX2N0eCxleGVfY3R4LG9wZXJhdGlvbixleHBlY3RlZF90eXBlKSB7CiAgICAgICAgICAgIEVycihlKSA9PiB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXJyKGUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBPayggbXV0IHN1Yl9leHByZXNzaW9ucyApID0+IHsKICAgICAgICBtYXRjaCBleHBlY3RlZF90eXBlIHsKICAgICAgICAgICAgVERfRGF0YVR5cGU6OkludGVnZXIgPT4gewogICAgICAgICAgICAgICAgbGV0IG11dCBmYWN0b3JfdmVjIDogVmVjPChBUklUSF9GQUNUT1JfU0lHTixURF9JbnRlZ2VyKT4gPSBWZWM6Om5ldygpOwogICAgICAgICAgICAgICAgbGV0IG11dCBmaXJzdCA6IGJvb2wgPSB0cnVlOwogICAgICAgICAgICAgICAgZm9yIHN1Yl9leHByIGluIHN1Yl9leHByZXNzaW9ucyB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggc3ViX2V4cHIgewogICAgICAgICAgICAgICAgICAgICAgICBURF9HZW5lcmljOjpJbnRlZ2VyKHRkX2ludCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZmlyc3QgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY3Rvcl92ZWMucHVzaCggKEFSSVRIX0ZBQ1RPUl9TSUdOOjpNdWx0LCB0ZF9pbnQpICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjdG9yX3ZlYy5wdXNoKCAoQVJJVEhfRkFDVE9SX1NJR046OkRpdiwgdGRfaW50KSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBfID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnIoIEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXRPcGVyYXRpb24ob3BlcmF0aW9uLmNsb25lKCkpICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gT2soIFREX0dlbmVyaWM6OkludGVnZXIoIFREX0ludGVnZXI6OkZhY3RvcihmYWN0b3JfdmVjKSApICk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIFREX0RhdGFUeXBlOjpGbG9hdCA9PiB7CiAgICAgICAgICAgICAgICBsZXQgbXV0IGZhY3Rvcl92ZWMgOiBWZWM8KEFSSVRIX0ZBQ1RPUl9TSUdOLFREX0Zsb2F0KT4gPSBWZWM6Om5ldygpOwogICAgICAgICAgICAgICAgbGV0IG11dCBmaXJzdCA6IGJvb2wgPSB0cnVlOwogICAgICAgICAgICAgICAgZm9yIHN1Yl9leHByIGluIHN1Yl9leHByZXNzaW9ucyB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggc3ViX2V4cHIgewogICAgICAgICAgICAgICAgICAgICAgICBURF9HZW5lcmljOjpGbG9hdCh0ZF9mbG9hdCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgZmlyc3QgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY3Rvcl92ZWMucHVzaCggKEFSSVRIX0ZBQ1RPUl9TSUdOOjpNdWx0LCB0ZF9mbG9hdCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3JfdmVjLnB1c2goIChBUklUSF9GQUNUT1JfU0lHTjo6RGl2LCB0ZF9mbG9hdCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgXyA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIE9rKCBURF9HZW5lcmljOjpGbG9hdCggVERfRmxvYXQ6OkZhY3RvcihmYWN0b3JfdmVjKSApICk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgICAgICAgICAgfQogICAgICAgIH19fQogICAgfSBlbHNlIGlmIG9wZXJhdGlvbi5vcGVyYXRvcl9raW5kID09ICggT3BlcmF0b3JLaW5kOjpPciBhcyBpMzIgKSB7CiAgICAgICAgbWF0Y2ggZ2V0X3N1Yl9leHByZXNzaW9ucyhnZW5fY3R4LGV4ZV9jdHgsb3BlcmF0aW9uLGV4cGVjdGVkX3R5cGUpIHsKICAgICAgICAgICAgRXJyKGUpID0+IHsKICAgICAgICAgICAgICAgIHJldHVybiBFcnIoZSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIE9rKCBtdXQgc3ViX2V4cHJlc3Npb25zICkgPT4gewogICAgICAgIG1hdGNoIGV4cGVjdGVkX3R5cGUgewogICAgICAgICAgICBURF9EYXRhVHlwZTo6Qm9vbCA9PiB7CiAgICAgICAgICAgICAgICBsZXQgbXV0IHN1Yl9ib29sX3ZlYyA6IFZlYzxURF9Cb29sPiA9IFZlYzo6bmV3KCk7CiAgICAgICAgICAgICAgICBmb3Igc3ViX2V4cHIgaW4gc3ViX2V4cHJlc3Npb25zIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaCBzdWJfZXhwciB7CiAgICAgICAgICAgICAgICAgICAgICAgIFREX0dlbmVyaWM6OkJvb2wodGRfYm9vbCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViX2Jvb2xfdmVjLnB1c2godGRfYm9vbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6Qm9vbCggVERfQm9vbDo6T1Ioc3ViX2Jvb2xfdmVjKSApICk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF8gPT4gewogICAgICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgICAgICAgICAgfQogICAgICAgIH19fQogICAgfSBlbHNlIGlmIG9wZXJhdGlvbi5vcGVyYXRvcl9raW5kID09ICggT3BlcmF0b3JLaW5kOjpBbmQgYXMgaTMyICkgewogICAgICAgIG1hdGNoIGdldF9zdWJfZXhwcmVzc2lvbnMoZ2VuX2N0eCxleGVfY3R4LG9wZXJhdGlvbixleHBlY3RlZF90eXBlKSB7CiAgICAgICAgICAgIEVycihlKSA9PiB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXJyKGUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBPayggbXV0IHN1Yl9leHByZXNzaW9ucyApID0+IHsKICAgICAgICBtYXRjaCBleHBlY3RlZF90eXBlIHsKICAgICAgICAgICAgVERfRGF0YVR5cGU6OkJvb2wgPT4gewogICAgICAgICAgICAgICAgbGV0IG11dCBzdWJfYm9vbF92ZWMgOiBWZWM8VERfQm9vbD4gPSBWZWM6Om5ldygpOwogICAgICAgICAgICAgICAgZm9yIHN1Yl9leHByIGluIHN1Yl9leHByZXNzaW9ucyB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggc3ViX2V4cHIgewogICAgICAgICAgICAgICAgICAgICAgICBURF9HZW5lcmljOjpCb29sKHRkX2Jvb2wpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Yl9ib29sX3ZlYy5wdXNoKHRkX2Jvb2wpOwogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBfID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnIoIEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXRPcGVyYXRpb24ob3BlcmF0aW9uLmNsb25lKCkpICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gT2soIFREX0dlbmVyaWM6OkJvb2woIFREX0Jvb2w6OkFORChzdWJfYm9vbF92ZWMpICkgKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgXyA9PiB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgICAgICB9CiAgICAgICAgfX19CiAgICB9IGVsc2UgaWYgb3BlcmF0aW9uLm9wZXJhdG9yX2tpbmQgPT0gKCBPcGVyYXRvcktpbmQ6Ok5vdCBhcyBpMzIgKSB7CiAgICAgICAgbWF0Y2ggZ2V0X3N1Yl9leHByZXNzaW9ucyhnZW5fY3R4LGV4ZV9jdHgsb3BlcmF0aW9uLGV4cGVjdGVkX3R5cGUpIHsKICAgICAgICAgICAgRXJyKGUpID0+IHsKICAgICAgICAgICAgICAgIHJldHVybiBFcnIoZSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIE9rKCBtdXQgc3ViX2V4cHJlc3Npb25zICkgPT4gewogICAgICAgIG1hdGNoIGV4cGVjdGVkX3R5cGUgewogICAgICAgICAgICBURF9EYXRhVHlwZTo6Qm9vbCA9PiB7CiAgICAgICAgICAgICAgICBpZiBzdWJfZXhwcmVzc2lvbnMubGVuKCkgIT0gMSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IHN1Yl9leHByID0gc3ViX2V4cHJlc3Npb25zLnJlbW92ZSgwKTsKICAgICAgICAgICAgICAgICAgICBtYXRjaCBzdWJfZXhwciB7CiAgICAgICAgICAgICAgICAgICAgICAgIFREX0dlbmVyaWM6OkJvb2wodGRfYm9vbCkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9rKCBURF9HZW5lcmljOjpCb29sKCBURF9Cb29sOjpOT1QoQm94OjpuZXcodGRfYm9vbCkpICkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgXyA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBfID0+IHsKICAgICAgICAgICAgICAgIHJldHVybiBFcnIoIEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXRPcGVyYXRpb24ob3BlcmF0aW9uLmNsb25lKCkpICk7CiAgICAgICAgICAgIH0KICAgICAgICB9fX0KICAgIH0gZWxzZSBpZiBvcGVyYXRpb24ub3BlcmF0b3Jfa2luZCA9PSAoIE9wZXJhdG9yS2luZDo6RXEgYXMgaTMyICkgewogICAgICAgIGlmIG9wZXJhdGlvbi5vcGVyYW5kLmxlbigpICE9IDIgfHwgZXhwZWN0ZWRfdHlwZSAhPSAmVERfRGF0YVR5cGU6OkJvb2wgewogICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1hdGNoIGdldF9icmFuY2hlc19vZl9jb21wYXJhaXNvbl9vcGVyYXRvcihnZW5fY3R4LGV4ZV9jdHgsb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICBFcnIoZSkgPT4gewogICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnIoZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgT2soIChnb3RfdHlwZSxtdXQgc3ViX2V4cHJlc3Npb25zKSApID0+IHsKICAgICAgICAgICAgICAgICAgICBsZXQgZmlyc3QgPSAgc3ViX2V4cHJlc3Npb25zLnJlbW92ZSgwKTsKICAgICAgICAgICAgICAgICAgICBsZXQgc2Vjb25kID0gc3ViX2V4cHJlc3Npb25zLnJlbW92ZSgwKTsKICAgICAgICAgICAgICAgICAgICBsZXQgdGRfYm9vbCA9IFREX0Jvb2w6OkNPTVBBUkUoQm9vbF9Db21wYXJlOjpFcXVhbCwgQm94OjpuZXcoZmlyc3QpLCBCb3g6Om5ldyhzZWNvbmQpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2soIFREX0dlbmVyaWM6OkJvb2woIHRkX2Jvb2wgKSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIGlmIG9wZXJhdGlvbi5vcGVyYXRvcl9raW5kID09ICggT3BlcmF0b3JLaW5kOjpOZXEgYXMgaTMyICkgewogICAgICAgIGlmIG9wZXJhdGlvbi5vcGVyYW5kLmxlbigpICE9IDIgfHwgZXhwZWN0ZWRfdHlwZSAhPSAmVERfRGF0YVR5cGU6OkJvb2wgewogICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1hdGNoIGdldF9icmFuY2hlc19vZl9jb21wYXJhaXNvbl9vcGVyYXRvcihnZW5fY3R4LGV4ZV9jdHgsb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICBFcnIoZSkgPT4gewogICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnIoZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgT2soIChnb3RfdHlwZSxtdXQgc3ViX2V4cHJlc3Npb25zKSApID0+IHsKICAgICAgICAgICAgICAgICAgICBsZXQgZmlyc3QgPSAgc3ViX2V4cHJlc3Npb25zLnJlbW92ZSgwKTsKICAgICAgICAgICAgICAgICAgICBsZXQgc2Vjb25kID0gc3ViX2V4cHJlc3Npb25zLnJlbW92ZSgwKTsKICAgICAgICAgICAgICAgICAgICBsZXQgdGRfYm9vbCA9IFREX0Jvb2w6OkNPTVBBUkUoQm9vbF9Db21wYXJlOjpEaWZmZXJlbnQsIEJveDo6bmV3KGZpcnN0KSwgQm94OjpuZXcoc2Vjb25kKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9rKCBURF9HZW5lcmljOjpCb29sKCB0ZF9ib29sICkgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBpZiBvcGVyYXRpb24ub3BlcmF0b3Jfa2luZCA9PSAoIE9wZXJhdG9yS2luZDo6R3QgYXMgaTMyICkgewogICAgICAgIGlmIG9wZXJhdGlvbi5vcGVyYW5kLmxlbigpICE9IDIgfHwgZXhwZWN0ZWRfdHlwZSAhPSAmVERfRGF0YVR5cGU6OkJvb2wgewogICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1hdGNoIGdldF9icmFuY2hlc19vZl9jb21wYXJhaXNvbl9vcGVyYXRvcihnZW5fY3R4LGV4ZV9jdHgsb3BlcmF0aW9uKSB7CiAgICAgICAgICAgICAgICBFcnIoZSkgPT4gewogICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnIoZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgT2soIChnb3RfdHlwZSxtdXQgc3ViX2V4cHJlc3Npb25zKSApID0+IHsKICAgICAgICAgICAgICAgICAgICBsZXQgZmlyc3QgPSAgc3ViX2V4cHJlc3Npb25zLnJlbW92ZSgwKTsKICAgICAgICAgICAgICAgICAgICBsZXQgc2Vjb25kID0gc3ViX2V4cHJlc3Npb25zLnJlbW92ZSgwKTsKICAgICAgICAgICAgICAgICAgICBsZXQgdGRfYm9vbCA9IFREX0Jvb2w6OkNPTVBBUkUoQm9vbF9Db21wYXJlOjpHcmVhdGVyLCBCb3g6Om5ldyhmaXJzdCksIEJveDo6bmV3KHNlY29uZCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6Qm9vbCggdGRfYm9vbCApICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgaWYgb3BlcmF0aW9uLm9wZXJhdG9yX2tpbmQgPT0gKCBPcGVyYXRvcktpbmQ6Okd0ZSBhcyBpMzIgKSB7CiAgICAgICAgaWYgb3BlcmF0aW9uLm9wZXJhbmQubGVuKCkgIT0gMiB8fCBleHBlY3RlZF90eXBlICE9ICZURF9EYXRhVHlwZTo6Qm9vbCB7CiAgICAgICAgICAgIHJldHVybiBFcnIoIEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXRPcGVyYXRpb24ob3BlcmF0aW9uLmNsb25lKCkpICk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbWF0Y2ggZ2V0X2JyYW5jaGVzX29mX2NvbXBhcmFpc29uX29wZXJhdG9yKGdlbl9jdHgsZXhlX2N0eCxvcGVyYXRpb24pIHsKICAgICAgICAgICAgICAgIEVycihlKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVycihlKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBPayggKGdvdF90eXBlLG11dCBzdWJfZXhwcmVzc2lvbnMpICkgPT4gewogICAgICAgICAgICAgICAgICAgIGxldCBmaXJzdCA9ICBzdWJfZXhwcmVzc2lvbnMucmVtb3ZlKDApOwogICAgICAgICAgICAgICAgICAgIGxldCBzZWNvbmQgPSBzdWJfZXhwcmVzc2lvbnMucmVtb3ZlKDApOwogICAgICAgICAgICAgICAgICAgIGxldCB0ZF9ib29sID0gVERfQm9vbDo6Q09NUEFSRShCb29sX0NvbXBhcmU6OkdyZWF0ZXJPckVxdWFsLCBCb3g6Om5ldyhmaXJzdCksIEJveDo6bmV3KHNlY29uZCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6Qm9vbCggdGRfYm9vbCApICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgaWYgb3BlcmF0aW9uLm9wZXJhdG9yX2tpbmQgPT0gKCBPcGVyYXRvcktpbmQ6Okx0IGFzIGkzMiApIHsKICAgICAgICBpZiBvcGVyYXRpb24ub3BlcmFuZC5sZW4oKSAhPSAyIHx8IGV4cGVjdGVkX3R5cGUgIT0gJlREX0RhdGFUeXBlOjpCb29sIHsKICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtYXRjaCBnZXRfYnJhbmNoZXNfb2ZfY29tcGFyYWlzb25fb3BlcmF0b3IoZ2VuX2N0eCxleGVfY3R4LG9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgRXJyKGUpID0+IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKGUpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIE9rKCAoZ290X3R5cGUsbXV0IHN1Yl9leHByZXNzaW9ucykgKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgbGV0IGZpcnN0ID0gIHN1Yl9leHByZXNzaW9ucy5yZW1vdmUoMCk7CiAgICAgICAgICAgICAgICAgICAgbGV0IHNlY29uZCA9IHN1Yl9leHByZXNzaW9ucy5yZW1vdmUoMCk7CiAgICAgICAgICAgICAgICAgICAgbGV0IHRkX2Jvb2wgPSBURF9Cb29sOjpDT01QQVJFKEJvb2xfQ29tcGFyZTo6TG93ZXIsIEJveDo6bmV3KGZpcnN0KSwgQm94OjpuZXcoc2Vjb25kKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9rKCBURF9HZW5lcmljOjpCb29sKCB0ZF9ib29sICkgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBpZiBvcGVyYXRpb24ub3BlcmF0b3Jfa2luZCA9PSAoIE9wZXJhdG9yS2luZDo6THRlIGFzIGkzMiApIHsKICAgICAgICBpZiBvcGVyYXRpb24ub3BlcmFuZC5sZW4oKSAhPSAyIHx8IGV4cGVjdGVkX3R5cGUgIT0gJlREX0RhdGFUeXBlOjpCb29sIHsKICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtYXRjaCBnZXRfYnJhbmNoZXNfb2ZfY29tcGFyYWlzb25fb3BlcmF0b3IoZ2VuX2N0eCxleGVfY3R4LG9wZXJhdGlvbikgewogICAgICAgICAgICAgICAgRXJyKGUpID0+IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKGUpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIE9rKCAoZ290X3R5cGUsbXV0IHN1Yl9leHByZXNzaW9ucykgKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgbGV0IGZpcnN0ID0gIHN1Yl9leHByZXNzaW9ucy5yZW1vdmUoMCk7CiAgICAgICAgICAgICAgICAgICAgbGV0IHNlY29uZCA9IHN1Yl9leHByZXNzaW9ucy5yZW1vdmUoMCk7CiAgICAgICAgICAgICAgICAgICAgbGV0IHRkX2Jvb2wgPSBURF9Cb29sOjpDT01QQVJFKEJvb2xfQ29tcGFyZTo6TG93ZXJPckVxdWFsLCBCb3g6Om5ldyhmaXJzdCksIEJveDo6bmV3KHNlY29uZCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6Qm9vbCggdGRfYm9vbCApICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFcnIoIEhpYm91Q29yZUVycm9yOjpVbmtub3duT3BlcmF0b3JJbkdycGNJbnB1dE9wZXJhdGlvbihvcGVyYXRpb24uY2xvbmUoKSkgKTsKICAgIH0KfQoKZm4gZ2V0X2JyYW5jaGVzX29mX2NvbXBhcmFpc29uX29wZXJhdG9yKGdlbl9jdHggOiAmR2VuZXJhbENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVfY3R4IDogJkV4ZWN1dGlvbkNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gOiAmT3BlcmF0aW9uKSAtPiBSZXN1bHQ8KFREX0RhdGFUeXBlLFZlYzwgVERfR2VuZXJpYyA+KSxIaWJvdUNvcmVFcnJvcj4gewoKICAgIG1hdGNoIGdldF9zdWJfZXhwcmVzc2lvbnMoZ2VuX2N0eCxleGVfY3R4LG9wZXJhdGlvbiwmVERfRGF0YVR5cGU6OlN0cmluZykgewogICAgICAgIEVycihlKSA9PiB7fQogICAgICAgIE9rKCBzdWJfZXhwcmVzc2lvbnMgKSA9PiB7CiAgICAgICAgICAgIHJldHVybiBPayggKFREX0RhdGFUeXBlOjpTdHJpbmcsIHN1Yl9leHByZXNzaW9ucykgKTsKICAgICAgICB9CiAgICB9CgogICAgbWF0Y2ggZ2V0X3N1Yl9leHByZXNzaW9ucyhnZW5fY3R4LGV4ZV9jdHgsb3BlcmF0aW9uLCZURF9EYXRhVHlwZTo6Qm9vbCkgewogICAgICAgIEVycihlKSA9PiB7fQogICAgICAgIE9rKCBzdWJfZXhwcmVzc2lvbnMgKSA9PiB7CiAgICAgICAgICAgIHJldHVybiBPayggKFREX0RhdGFUeXBlOjpCb29sLCBzdWJfZXhwcmVzc2lvbnMpICk7CiAgICAgICAgfQogICAgfQoKICAgIG1hdGNoIGdldF9zdWJfZXhwcmVzc2lvbnMoZ2VuX2N0eCxleGVfY3R4LG9wZXJhdGlvbiwmVERfRGF0YVR5cGU6OkludGVnZXIpIHsKICAgICAgICBFcnIoZSkgPT4ge30KICAgICAgICBPayggc3ViX2V4cHJlc3Npb25zICkgPT4gewogICAgICAgICAgICByZXR1cm4gT2soIChURF9EYXRhVHlwZTo6SW50ZWdlciwgc3ViX2V4cHJlc3Npb25zKSApOwogICAgICAgIH0KICAgIH0KCiAgICBtYXRjaCBnZXRfc3ViX2V4cHJlc3Npb25zKGdlbl9jdHgsZXhlX2N0eCxvcGVyYXRpb24sJlREX0RhdGFUeXBlOjpGbG9hdCkgewogICAgICAgIEVycihlKSA9PiB7fQogICAgICAgIE9rKCBzdWJfZXhwcmVzc2lvbnMgKSA9PiB7CiAgICAgICAgICAgIHJldHVybiBPayggKFREX0RhdGFUeXBlOjpGbG9hdCwgc3ViX2V4cHJlc3Npb25zKSApOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0T3BlcmF0aW9uKG9wZXJhdGlvbi5jbG9uZSgpKSApCn0KCgoKcHViIGZuIGV4cHJlc3Npb25fZnJvbV9ncnBjKGdlbl9jdHggOiAmR2VuZXJhbENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVfY3R4IDogJkV4ZWN1dGlvbkNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uIDogJkV4cHJlc3Npb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZF90eXBlIDogJlREX0RhdGFUeXBlICkgLT4gUmVzdWx0PFREX0dlbmVyaWMsSGlib3VDb3JlRXJyb3I+IHsKICAgIG1hdGNoICZleHByZXNzaW9uLmV4cHJlc3Npb25fYWx0IHsKICAgICAgICBOb25lID0+IHsKICAgICAgICAgICAgcGFuaWMhKCJmb3JiaWRkZW4gZW1wdHkgZXhwcmVzc2lvbiIpOwogICAgICAgIH0sCiAgICAgICAgU29tZSggZXhwcmVzc2lvbl9hbHQgKSA9PiB7CiAgICAgICAgICAgIG1hdGNoIGV4cHJlc3Npb25fYWx0IHsKICAgICAgICAgICAgICAgIEV4cHJlc3Npb25BbHQ6OlN5bWJvbElkKCBzeW1ib2xfZnFuICkgPT4gewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1ib2xfcmVmZXJlbmNlX2Zyb21fZ3JwYyhnZW5fY3R4LGV4ZV9jdHgsc3ltYm9sX2ZxbixleHBlY3RlZF90eXBlKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBFeHByZXNzaW9uQWx0OjpWYXJpYWJsZUlkKCB2YXJpYWJsZV9mcW4gKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgLy9ESVZFUlNJVFkgc2hvdWxkIG9ubHkgcmV0dXJuIHRlcm1zIG9mIHN5bWJvbHM7IG5vIHZhcmlhYmxlcyBzaG91bGQgYXBwZWFyIGluIHRob3NlIHRlcm1zCiAgICAgICAgICAgICAgICAgICAgcGFuaWMhKCk7CiAgICAgICAgICAgICAgICAgICAgLy9yZXR1cm4gdmFyaWFibGVfcmVmZXJlbmNlX2Zyb21fZ3JwYyhnZW5fY3R4LGV4ZV9jdHgsdmFyX2lkKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBFeHByZXNzaW9uQWx0OjpPcGVyYXRpb24oIHN1Yl9vcGVyYXRpb24gKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wZXJhdGlvbl9mcm9tX2dycGMoZ2VuX2N0eCxleGVfY3R4LHN1Yl9vcGVyYXRpb24sZXhwZWN0ZWRfdHlwZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgRXhwcmVzc2lvbkFsdDo6UmF3U3RyaW5nKCByYXdfc3RyaW5nICkgPT4gewogICAgICAgICAgICAgICAgICAgIGlmIGV4cGVjdGVkX3R5cGUgPT0gJlREX0RhdGFUeXBlOjpTdHJpbmcgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gT2soIFREX0dlbmVyaWM6OlN0cmluZyhURF9TdHJpbmc6OlZhbHVlKHJhd19zdHJpbmcuY2xvbmUoKSkpICk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVyciggSGlib3VDb3JlRXJyb3I6Oldyb25nbHlUeXBlZEdycGNJbnB1dChyYXdfc3RyaW5nLmNsb25lKCksIGV4cGVjdGVkX3R5cGUuY2xvbmUoKSwgVERfRGF0YVR5cGU6OlN0cmluZy5hc194bGlhX3N0cigpICkgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgRXhwcmVzc2lvbkFsdDo6UmF3SW50ZWdlciggcmF3X2ludCApID0+IHsKICAgICAgICAgICAgICAgICAgICBpZiBleHBlY3RlZF90eXBlID09ICZURF9EYXRhVHlwZTo6SW50ZWdlciB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6SW50ZWdlcihURF9JbnRlZ2VyOjpWYWx1ZSggKnJhd19pbnQgYXMgaTY0ICkpICk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIGV4cGVjdGVkX3R5cGUgPT0gJlREX0RhdGFUeXBlOjpGbG9hdCB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6RmxvYXQoVERfRmxvYXQ6OlZhbHVlKCAqcmF3X2ludCBhcyBmNjQgKSkgKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0KHJhd19pbnQudG9fc3RyaW5nKCksIGV4cGVjdGVkX3R5cGUuY2xvbmUoKSwgZm9ybWF0ISgie30gb3Ige30iLFREX0RhdGFUeXBlOjpJbnRlZ2VyLmFzX3hsaWFfc3RyKCksVERfRGF0YVR5cGU6OkZsb2F0LmFzX3hsaWFfc3RyKCkpICkgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgRXhwcmVzc2lvbkFsdDo6UmF3RmxvYXQoIHJhd19mbG9hdCApID0+IHsKICAgICAgICAgICAgICAgICAgICBpZiBleHBlY3RlZF90eXBlID09ICZURF9EYXRhVHlwZTo6SW50ZWdlciB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgqcmF3X2Zsb2F0KS5mcmFjdCgpICE9IDAuMCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0KHJhd19mbG9hdC50b19zdHJpbmcoKSwgZXhwZWN0ZWRfdHlwZS5jbG9uZSgpLCBmb3JtYXQhKCJ7fSBvciB7fSIsVERfRGF0YVR5cGU6OkludGVnZXIuYXNfeGxpYV9zdHIoKSxURF9EYXRhVHlwZTo6RmxvYXQuYXNfeGxpYV9zdHIoKSkgKSApOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9rKCBURF9HZW5lcmljOjpJbnRlZ2VyKFREX0ludGVnZXI6OlZhbHVlKCAqcmF3X2Zsb2F0IGFzIGk2NCApKSApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIGV4cGVjdGVkX3R5cGUgPT0gJlREX0RhdGFUeXBlOjpGbG9hdCB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPayggVERfR2VuZXJpYzo6RmxvYXQoVERfRmxvYXQ6OlZhbHVlKCAqcmF3X2Zsb2F0IGFzIGY2NCApKSApOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnIoIEhpYm91Q29yZUVycm9yOjpXcm9uZ2x5VHlwZWRHcnBjSW5wdXQocmF3X2Zsb2F0LnRvX3N0cmluZygpLCBleHBlY3RlZF90eXBlLmNsb25lKCksIGZvcm1hdCEoInt9IG9yIHt9IixURF9EYXRhVHlwZTo6SW50ZWdlci5hc194bGlhX3N0cigpLFREX0RhdGFUeXBlOjpGbG9hdC5hc194bGlhX3N0cigpKSApICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIEV4cHJlc3Npb25BbHQ6OlJhd0Jvb2woIHJhd19ib29sICkgPT4gewogICAgICAgICAgICAgICAgICAgIGlmIGV4cGVjdGVkX3R5cGUgPT0gJlREX0RhdGFUeXBlOjpCb29sIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRkX2dlbiA6IFREX0dlbmVyaWM7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICpyYXdfYm9vbCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZF9nZW4gPSBURF9HZW5lcmljOjpCb29sKFREX0Jvb2w6OlRSVUUpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGRfZ2VuID0gVERfR2VuZXJpYzo6Qm9vbChURF9Cb29sOjpGQUxTRSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9rKCB0ZF9nZW4gKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXJyKCBIaWJvdUNvcmVFcnJvcjo6V3JvbmdseVR5cGVkR3JwY0lucHV0KHJhd19ib29sLnRvX3N0cmluZygpLCBleHBlY3RlZF90eXBlLmNsb25lKCksIFREX0RhdGFUeXBlOjpCb29sLmFzX3hsaWFfc3RyKCkgKSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQ==