LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKEMpIDIwMTUtMjAxNyBieSBTYXZvaXItZmFpcmUgTGludXggICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIEF1dGhvcjogRWRyaWMgTGFkZW50IE1pbGFyZXQgPGVkcmljLmxhZGVudC1taWxhcmV0QHNhdm9pcmZhaXJlbGludXguY29tPioKICogQXV0aG9yOiBBbmRyZWFzIFRyYWN6eWsgPGFuZHJlYXMudHJhY3p5a0BzYXZvaXJmYWlyZWxpbnV4LmNvbT4gICAgICAgICAgKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5ICAgICoKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgICAgKgogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvciAgICAgICAqCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgICAgICAgICAqCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mICAgICAgICAgICoKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSAgICAgICAgICAgKgogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgICAgICAgKgogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4gICAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJjb252ZXJzYXRpb25pdGVtZGVsZWdhdGUuaCIKCiNpbmNsdWRlIDxRQXBwbGljYXRpb24+CiNpbmNsdWRlIDxRUGFpbnRlcj4KI2luY2x1ZGUgPFFQaXhtYXA+CgovLyBDbGllbnQKI2luY2x1ZGUgInNtYXJ0bGlzdG1vZGVsLmgiCiNpbmNsdWRlICJyaW5ndGhlbWV1dGlscy5oIgojaW5jbHVkZSAidXRpbHMuaCIKI2luY2x1ZGUgImxyY2luc3RhbmNlLmgiCiNpbmNsdWRlICJtYWlud2luZG93LmgiCgojaW5jbHVkZSA8Y2lzbzY0Nj4KCkNvbnZlcnNhdGlvbkl0ZW1EZWxlZ2F0ZTo6Q29udmVyc2F0aW9uSXRlbURlbGVnYXRlKFFPYmplY3QqIHBhcmVudCkKICAgIDogUUl0ZW1EZWxlZ2F0ZShwYXJlbnQpCnsKfQoKdm9pZApDb252ZXJzYXRpb25JdGVtRGVsZWdhdGU6OnBhaW50KFFQYWludGVyKiBwYWludGVyCiAgICAgICAgICAgICAgICAgICAgICAgICwgY29uc3QgUVN0eWxlT3B0aW9uVmlld0l0ZW0mIG9wdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAsIGNvbnN0IFFNb2RlbEluZGV4JiBpbmRleAogICAgICAgICAgICAgICAgICAgICAgICApIGNvbnN0CnsKICAgIFFTdHlsZU9wdGlvblZpZXdJdGVtIG9wdChvcHRpb24pOwogICAgcGFpbnRlci0+c2V0UmVuZGVySGludChRUGFpbnRlcjo6QW50aWFsaWFzaW5nLCB0cnVlKTsKCiAgICAvLyBOb3QgaGF2aW5nIGZvY3VzIHJlbW92ZXMgZG90dGVkIGxpbmVzIGFyb3VuZCB0aGUgaXRlbQogICAgaWYgKG9wdC5zdGF0ZSAmIFFTdHlsZTo6U3RhdGVfSGFzRm9jdXMpCiAgICAgICAgb3B0LnN0YXRlIF49IFFTdHlsZTo6U3RhdGVfSGFzRm9jdXM7CgogICAgYXV0byBpc0NvbnRleHRNZW51T3BlbiA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6Q29udGV4dE1lbnVPcGVuKSkudmFsdWU8Ym9vbD4oKTsKICAgIGJvb2wgc2VsZWN0ZWQgPSBmYWxzZTsKICAgIGlmIChvcHRpb24uc3RhdGUgJiBRU3R5bGU6OlN0YXRlX1NlbGVjdGVkKSB7CiAgICAgICAgc2VsZWN0ZWQgPSB0cnVlOwogICAgICAgIG9wdC5zdGF0ZSBePSBRU3R5bGU6OlN0YXRlX1NlbGVjdGVkOwogICAgfSBlbHNlIGlmICghaXNDb250ZXh0TWVudU9wZW4pIHsKICAgICAgICBoaWdobGlnaHRNYXBfW2luZGV4LnJvdygpXSA9IG9wdGlvbi5zdGF0ZSAmIFFTdHlsZTo6U3RhdGVfTW91c2VPdmVyOwogICAgfQoKICAgIC8vIE9uZSBkb2VzIG5vdCBzaW1wbHkga2VlcCB0aGUgaGlnaGxpZ2h0ZWQgc3RhdGUgZHJhd24gd2hlbiB0aGUgY29udGV4dAogICAgLy8gbWVudSBpcyBvcGVuhQogICAgUUNvbG9yIHByZXNlbmNlQm9yZGVyQ29sb3IgPSBRdDo6d2hpdGU7CiAgICBhdXRvIHJvd0hpZ2hsaWdodCA9IGhpZ2hsaWdodE1hcF8uZmluZChpbmRleC5yb3coKSk7CiAgICBpZiAoc2VsZWN0ZWQpIHsKICAgICAgIHBhaW50ZXItPmZpbGxSZWN0KG9wdGlvbi5yZWN0LCBSaW5nVGhlbWU6OnNtYXJ0bGlzdFNlbGVjdGlvbl8pOwogICAgICAgcHJlc2VuY2VCb3JkZXJDb2xvciA9IFJpbmdUaGVtZTo6c21hcnRsaXN0U2VsZWN0aW9uXzsKICAgIH0gZWxzZSBpZiAocm93SGlnaGxpZ2h0ICE9IGhpZ2hsaWdodE1hcF8uZW5kKCkgJiYgKCpyb3dIaWdobGlnaHQpLnNlY29uZCkgewogICAgICAgcGFpbnRlci0+ZmlsbFJlY3Qob3B0aW9uLnJlY3QsIFJpbmdUaGVtZTo6c21hcnRsaXN0SGlnaGxpZ2h0Xyk7CiAgICAgICBwcmVzZW5jZUJvcmRlckNvbG9yID0gUmluZ1RoZW1lOjpzbWFydGxpc3RIaWdobGlnaHRfOwogICAgfQogICAgYXV0byBjb252VWlkID0gaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpVSUQpKS52YWx1ZTxRU3RyaW5nPigpLnRvU3RkU3RyaW5nKCk7CiAgICBhdXRvIGNvbnZlcnNhdGlvbiA9IFV0aWxzOjpnZXRDb252ZXJzYXRpb25Gcm9tVWlkKGNvbnZVaWQsICpMUkNJbnN0YW5jZTo6Z2V0Q3VycmVudENvbnZlcnNhdGlvbk1vZGVsKCkpOwogICAgaWYgKExSQ0luc3RhbmNlOjpnZXRDdXJyZW50Q2FsbE1vZGVsKCktPmhhc0NhbGwoY29udmVyc2F0aW9uLT5jYWxsSWQpKSB7CiAgICAgICAgYXV0byBjb2xvciA9IFFDb2xvcihSaW5nVGhlbWU6OmJsdWVfLmxpZ2h0ZXIoMTgwKSk7CiAgICAgICAgcHJlc2VuY2VCb3JkZXJDb2xvciA9IGNvbG9yOwogICAgICAgIGNvbG9yLnNldEFscGhhKDEyOCk7CiAgICAgICAgcGFpbnRlci0+ZmlsbFJlY3Qob3B0aW9uLnJlY3QsIGNvbG9yKTsKICAgIH0KCiAgICBRUmVjdCAmcmVjdCA9IG9wdC5yZWN0OwoKICAgIC8vIEF2YXRhciBkcmF3aW5nCiAgICBvcHQuZGVjb3JhdGlvblNpemUgPSBRU2l6ZShzaXplSW1hZ2VfLCBzaXplSW1hZ2VfKTsKICAgIG9wdC5kZWNvcmF0aW9uUG9zaXRpb24gPSBRU3R5bGVPcHRpb25WaWV3SXRlbTo6TGVmdDsKICAgIG9wdC5kZWNvcmF0aW9uQWxpZ25tZW50ID0gUXQ6OkFsaWduQ2VudGVyOwoKICAgIFFSZWN0IHJlY3RBdmF0YXIoZHhfICsgcmVjdC5sZWZ0KCksIHJlY3QudG9wKCkgKyBkeV8sIHNpemVJbWFnZV8sIHNpemVJbWFnZV8pOwogICAgZHJhd0RlY29yYXRpb24ocGFpbnRlciwgb3B0LCByZWN0QXZhdGFyLAogICAgICAgICAgICAgICAgICAgUVBpeG1hcDo6ZnJvbUltYWdlKGluZGV4LmRhdGEoUXQ6OkRlY29yYXRpb25Sb2xlKS52YWx1ZTxRSW1hZ2U+KCkpCiAgICAgICAgICAgICAgICAgICAuc2NhbGVkKHNpemVJbWFnZV8sIHNpemVJbWFnZV8sIFF0OjpLZWVwQXNwZWN0UmF0aW8sIFF0OjpTbW9vdGhUcmFuc2Zvcm1hdGlvbikpOwoKICAgIFFGb250IGZvbnQocGFpbnRlci0+Zm9udCgpKTsKCiAgICAvLyBJZiB0aGVyZSdzIHVucmVhZCBtZXNzYWdlcywgYSBtZXNzYWdlIGNvdW50IGlzIGRpc3BsYXllZAogICAgaWYgKGF1dG8gbWVzc2FnZUNvdW50ID0gaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpVbnJlYWRNZXNzYWdlc0NvdW50KSkudG9JbnQoKSkgewogICAgICAgIFFTdHJpbmcgbWVzc2FnZUNvdW50VGV4dCA9IChtZXNzYWdlQ291bnQgPiA5KSA/ICI5KyIgOiBRU3RyaW5nOjpudW1iZXIobWVzc2FnZUNvdW50KTsKICAgICAgICBxcmVhbCBmb250U2l6ZSA9IG1lc3NhZ2VDb3VudFRleHQuY291bnQoKSA+IDEgPyA3IDogODsKICAgICAgICBmb250LnNldFBvaW50U2l6ZShmb250U2l6ZSk7CgogICAgICAgIC8vIGVsbGlwc2UKICAgICAgICBRUGFpbnRlclBhdGggZWxsaXBzZTsKICAgICAgICBxcmVhbCBlbGxpcHNlSGVpZ2h0ID0gc2l6ZUltYWdlXyAvIDY7CiAgICAgICAgcXJlYWwgZWxsaXBzZVdpZHRoID0gZWxsaXBzZUhlaWdodDsKICAgICAgICBRUG9pbnRGIGVsbGlwc2VDZW50ZXIocmVjdEF2YXRhci5yaWdodCgpIC0gZWxsaXBzZVdpZHRoICsgMSwgcmVjdEF2YXRhci50b3AoKSArIGVsbGlwc2VIZWlnaHQgKyAxKTsKICAgICAgICBRUmVjdCBlbGxpcHNlUmVjdChlbGxpcHNlQ2VudGVyLngoKSAtIGVsbGlwc2VXaWR0aCwgZWxsaXBzZUNlbnRlci55KCkgLSBlbGxpcHNlSGVpZ2h0LAogICAgICAgICAgICBlbGxpcHNlV2lkdGggKiAyLCBlbGxpcHNlSGVpZ2h0ICogMik7CiAgICAgICAgZWxsaXBzZS5hZGRSb3VuZGVkUmVjdChlbGxpcHNlUmVjdCwgZWxsaXBzZVdpZHRoLCBlbGxpcHNlSGVpZ2h0KTsKICAgICAgICBwYWludGVyLT5maWxsUGF0aChlbGxpcHNlLCBSaW5nVGhlbWU6Om5vdGlmaWNhdGlvblJlZF8pOwoKICAgICAgICAvLyB0ZXh0CiAgICAgICAgcGFpbnRlci0+c2V0UGVuKFF0Ojp3aGl0ZSk7CiAgICAgICAgcGFpbnRlci0+c2V0T3BhY2l0eSgxKTsKICAgICAgICBwYWludGVyLT5zZXRGb250KGZvbnQpOwogICAgICAgIGVsbGlwc2VSZWN0LnNldFRvcChlbGxpcHNlUmVjdC50b3AoKSAtIDIpOwogICAgICAgIHBhaW50ZXItPmRyYXdUZXh0KGVsbGlwc2VSZWN0LCBRdDo6QWxpZ25DZW50ZXIsIG1lc3NhZ2VDb3VudFRleHQpOwogICAgfQoKICAgIC8vIFByZXNlbmNlIGluZGljYXRvcgogICAgaWYgKGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6UHJlc2VuY2UpKS52YWx1ZTxib29sPigpKSB7CiAgICAgICAgcXJlYWwgcmFkaXVzID0gc2l6ZUltYWdlXyAvIDY7CiAgICAgICAgUVBhaW50ZXJQYXRoIG91dGVyQ2lyY2xlLCBpbm5lckNpcmNsZTsKICAgICAgICBRUG9pbnRGIGNlbnRlcihyZWN0QXZhdGFyLnJpZ2h0KCkgLSByYWRpdXMgKyAyLCAocmVjdEF2YXRhci5ib3R0b20oKSAtIHJhZGl1cykgKyAxICsgMik7CiAgICAgICAgcXJlYWwgb3V0ZXJDUmFkaXVzID0gcmFkaXVzOwogICAgICAgIHFyZWFsIGlubmVyQ1JhZGl1cyA9IG91dGVyQ1JhZGl1cyAqIDAuNzU7CiAgICAgICAgb3V0ZXJDaXJjbGUuYWRkRWxsaXBzZShjZW50ZXIsIG91dGVyQ1JhZGl1cywgb3V0ZXJDUmFkaXVzKTsKICAgICAgICBpbm5lckNpcmNsZS5hZGRFbGxpcHNlKGNlbnRlciwgaW5uZXJDUmFkaXVzLCBpbm5lckNSYWRpdXMpOwogICAgICAgIHBhaW50ZXItPmZpbGxQYXRoKG91dGVyQ2lyY2xlLCBwcmVzZW5jZUJvcmRlckNvbG9yKTsKICAgICAgICBwYWludGVyLT5maWxsUGF0aChpbm5lckNpcmNsZSwgUmluZ1RoZW1lOjpwcmVzZW5jZUdyZWVuXyk7CiAgICB9CgogICAgdXNpbmcgbmFtZXNwYWNlIGxyYzo6YXBpOwogICAgYXV0byB0eXBlID0gVXRpbHM6OnRvRW51bTxwcm9maWxlOjpUeXBlPigKICAgICAgICAgICAgaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpDb250YWN0VHlwZSkpLnZhbHVlPGludD4oKQogICAgICAgICk7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgcHJvZmlsZTo6VHlwZTo6UklORzoKICAgIGNhc2UgcHJvZmlsZTo6VHlwZTo6VEVNUE9SQVJZOgogICAgICAgIHBhaW50UmluZ0NvbnZlcnNhdGlvbkl0ZW0ocGFpbnRlciwgb3B0aW9uLCByZWN0LCBpbmRleCk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIHByb2ZpbGU6OlR5cGU6OlBFTkRJTkc6CiAgICAgICAgcGFpbnRSaW5nSW52aXRlQ29udmVyc2F0aW9uSXRlbShwYWludGVyLCBvcHRpb24sIHJlY3QsIGluZGV4KTsKICAgICAgICBicmVhazsKICAgIGNhc2UgcHJvZmlsZTo6VHlwZTo6U0lQOgogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBwYWludFJpbmdDb252ZXJzYXRpb25JdGVtKHBhaW50ZXIsIG9wdGlvbiwgcmVjdCwgaW5kZXgpOwogICAgICAgIGJyZWFrOwogICAgfQp9CgpRU2l6ZQpDb252ZXJzYXRpb25JdGVtRGVsZWdhdGU6OnNpemVIaW50KGNvbnN0IFFTdHlsZU9wdGlvblZpZXdJdGVtJiBvcHRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUU1vZGVsSW5kZXgmIGluZGV4KSBjb25zdAp7CiAgICBRX1VOVVNFRChvcHRpb24pOwogICAgUV9VTlVTRUQoaW5kZXgpOwogICAgcmV0dXJuIFFTaXplKDAsIGNlbGxIZWlnaHRfKTsKfQoKdm9pZApDb252ZXJzYXRpb25JdGVtRGVsZWdhdGU6OnBhaW50UmluZ0NvbnZlcnNhdGlvbkl0ZW0oUVBhaW50ZXIqIHBhaW50ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRU3R5bGVPcHRpb25WaWV3SXRlbSYgb3B0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUVJlY3QmIHJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRTW9kZWxJbmRleCYgaW5kZXgpIGNvbnN0CnsKICAgIFFfVU5VU0VEKG9wdGlvbik7CiAgICBRRm9udCBmb250KHBhaW50ZXItPmZvbnQoKSk7CiAgICBRUGVuIHBlbihwYWludGVyLT5wZW4oKSk7CiAgICBwYWludGVyLT5zZXRQZW4ocGVuKTsKCiAgICBpbnQgaW5mb1RleHRXaWR0aE1vZGlmaWVyID0gMDsKICAgIGludCBpbmZvVGV4dDJIZWlnaHRNb2RpZmllciA9IDA7CiAgICBhdXRvIHNjYWxpbmdSYXRpbyA9IE1haW5XaW5kb3c6Omluc3RhbmNlKCkuZ2V0Q3VycmVudFNjYWxpbmdSYXRpbygpOwogICAgaWYgKHNjYWxpbmdSYXRpbyA+IDEuMCkgewogICAgICAgIGZvbnQuc2V0UG9pbnRTaXplKGZvbnRTaXplXyAtIDIpOwogICAgICAgIGluZm9UZXh0V2lkdGhNb2RpZmllciA9IDEyOwogICAgICAgIGluZm9UZXh0MkhlaWdodE1vZGlmaWVyID0gMjsKICAgIH0gZWxzZSB7CiAgICAgICAgZm9udC5zZXRQb2ludFNpemUoZm9udFNpemVfKTsKICAgICAgICBpbmZvVGV4dFdpZHRoTW9kaWZpZXIgPSAxMDsKICAgIH0KCiAgICBhdXRvIGxlZnRNYXJnaW4gPSBkeF8gKyBzaXplSW1hZ2VfICsgZHhfOwogICAgYXV0byByaWdodE1hcmdpbiA9IGR4XzsKICAgIGF1dG8gdG9wTWFyZ2luID0gNDsKICAgIGF1dG8gYm90dG9tTWFyZ2luID0gODsKCiAgICBRUmVjdCByZWN0TmFtZTEocmVjdC5sZWZ0KCkgKyBsZWZ0TWFyZ2luLAogICAgICAgICAgICAgICAgICAgIHJlY3QudG9wKCkgKyB0b3BNYXJnaW4sCiAgICAgICAgICAgICAgICAgICAgcmVjdC53aWR0aCgpIC0gbGVmdE1hcmdpbiAtIGluZm9UZXh0V2lkdGhfIC0gaW5mb1RleHRXaWR0aE1vZGlmaWVyIC0gNCwKICAgICAgICAgICAgICAgICAgICByZWN0LmhlaWdodCgpIC8gMiAtIDIpOwoKICAgIFFSZWN0IHJlY3ROYW1lMihyZWN0TmFtZTEubGVmdCgpLAogICAgICAgICAgICAgICAgICAgIHJlY3ROYW1lMS50b3AoKSArIHJlY3ROYW1lMS5oZWlnaHQoKSAtIGluZm9UZXh0MkhlaWdodE1vZGlmaWVyLAogICAgICAgICAgICAgICAgICAgIHJlY3ROYW1lMS53aWR0aCgpLAogICAgICAgICAgICAgICAgICAgIHJlY3ROYW1lMS5oZWlnaHQoKSAtIGJvdHRvbU1hcmdpbiArIGluZm9UZXh0MkhlaWdodE1vZGlmaWVyKTsKCiAgICBRUmVjdCByZWN0SW5mbzEocmVjdE5hbWUxLmxlZnQoKSArIHJlY3ROYW1lMS53aWR0aCgpLAogICAgICAgICAgICAgICAgICAgIHJlY3QudG9wKCkgKyB0b3BNYXJnaW4sCiAgICAgICAgICAgICAgICAgICAgaW5mb1RleHRXaWR0aF8gLSByaWdodE1hcmdpbiArIGluZm9UZXh0V2lkdGhNb2RpZmllciArIDIsCiAgICAgICAgICAgICAgICAgICAgcmVjdC5oZWlnaHQoKSAvIDIgLSAyKTsKCiAgICBRUmVjdCByZWN0SW5mbzIocmVjdEluZm8xLmxlZnQoKSwKICAgICAgICAgICAgICAgICAgICByZWN0SW5mbzEudG9wKCkgKyByZWN0SW5mbzEuaGVpZ2h0KCkgLSBpbmZvVGV4dDJIZWlnaHRNb2RpZmllciwKICAgICAgICAgICAgICAgICAgICByZWN0SW5mbzEud2lkdGgoKSwKICAgICAgICAgICAgICAgICAgICByZWN0SW5mbzEuaGVpZ2h0KCkgLSBib3R0b21NYXJnaW4gKyBpbmZvVGV4dDJIZWlnaHRNb2RpZmllcik7CgogICAgUUZvbnRNZXRyaWNzIGZvbnRNZXRyaWNzKGZvbnQpOwoKICAgIC8vIFRoZSBuYW1lIGlzIGRpc3BsYXllZCBhdCB0aGUgYXZhdGFyJ3MgcmlnaHQKICAgIFFTdHJpbmcgbmFtZVN0ciA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6RGlzcGxheU5hbWUpKS52YWx1ZTxRU3RyaW5nPigpOwogICAgaWYgKCFuYW1lU3RyLmlzTnVsbCgpKSB7CiAgICAgICAgZm9udC5zZXRJdGFsaWMoZmFsc2UpOwogICAgICAgIGZvbnQuc2V0Qm9sZChmYWxzZSk7CiAgICAgICAgcGVuLnNldENvbG9yKFJpbmdUaGVtZTo6bGlnaHRCbGFja18pOwogICAgICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwogICAgICAgIHBhaW50ZXItPnNldEZvbnQoZm9udCk7CiAgICAgICAgUVN0cmluZyBlbGlkZWROYW1lU3RyID0gZm9udE1ldHJpY3MuZWxpZGVkVGV4dChuYW1lU3RyLCBRdDo6RWxpZGVSaWdodCwgcmVjdE5hbWUxLndpZHRoKCkpOwogICAgICAgIHBhaW50ZXItPmRyYXdUZXh0KHJlY3ROYW1lMSwgUXQ6OkFsaWduVkNlbnRlciB8IFF0OjpBbGlnbkxlZnQsIGVsaWRlZE5hbWVTdHIpOwogICAgfQoKICAgIC8vIERpc3BsYXkgdGhlIElEIHVuZGVyIHRoZSBuYW1lCiAgICBRU3RyaW5nIGlkU3RyID0gaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpEaXNwbGF5SUQpKS52YWx1ZTxRU3RyaW5nPigpOwogICAgaWYgKGlkU3RyICE9IG5hbWVTdHIgJiYgIWlkU3RyLmlzTnVsbCgpKSB7CiAgICAgICAgZm9udC5zZXRJdGFsaWMoZmFsc2UpOwogICAgICAgIGZvbnQuc2V0Qm9sZChmYWxzZSk7CiAgICAgICAgcGVuLnNldENvbG9yKFJpbmdUaGVtZTo6Z3JleV8pOwogICAgICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwogICAgICAgIHBhaW50ZXItPnNldEZvbnQoZm9udCk7CiAgICAgICAgaWRTdHIgPSBmb250TWV0cmljcy5lbGlkZWRUZXh0KGlkU3RyLCBRdDo6RWxpZGVSaWdodCwgcmVjdE5hbWUyLndpZHRoKCkpOwogICAgICAgIHBhaW50ZXItPmRyYXdUZXh0KHJlY3ROYW1lMiwgUXQ6OkFsaWduVkNlbnRlciB8IFF0OjpBbGlnbkxlZnQsIGlkU3RyKTsKICAgIH0KCiAgICAvLyB0b3AtcmlnaHQ6IGxhc3QgaW50ZXJhY3Rpb24gZGF0ZS90aW1lCiAgICBRU3RyaW5nIGxhc3RVc2VkU3RyID0gaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpMYXN0SW50ZXJhY3Rpb25EYXRlKSkudmFsdWU8UVN0cmluZz4oKTsKICAgIGlmICghbGFzdFVzZWRTdHIuaXNOdWxsKCkpIHsKICAgICAgICBmb250LnNldEl0YWxpYyhmYWxzZSk7CiAgICAgICAgZm9udC5zZXRCb2xkKGZhbHNlKTsKICAgICAgICBwZW4uc2V0Q29sb3IoUmluZ1RoZW1lOjpncmV5Xyk7CiAgICAgICAgcGFpbnRlci0+c2V0UGVuKHBlbik7CiAgICAgICAgcGFpbnRlci0+c2V0Rm9udChmb250KTsKICAgICAgICBsYXN0VXNlZFN0ciA9IGZvbnRNZXRyaWNzLmVsaWRlZFRleHQobGFzdFVzZWRTdHIsIFF0OjpFbGlkZVJpZ2h0LCByZWN0SW5mbzEud2lkdGgoKSk7CiAgICAgICAgcGFpbnRlci0+ZHJhd1RleHQocmVjdEluZm8xLCBRdDo6QWxpZ25WQ2VudGVyIHwgUXQ6OkFsaWduUmlnaHQsIGxhc3RVc2VkU3RyKTsKICAgIH0KCiAgICAvLyBib3R0b20tcmlnaHQ6IGxhc3QgaW50ZXJhY3Rpb24gc25pcHBldAogICAgUVN0cmluZyBpbnRlcmFjdGlvblN0ciA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6TGFzdEludGVyYWN0aW9uKSkudmFsdWU8UVN0cmluZz4oKTsKICAgIGlmICghaW50ZXJhY3Rpb25TdHIuaXNOdWxsKCkpIHsKICAgICAgICBwYWludGVyLT5zYXZlKCk7CiAgICAgICAgZm9udC5zZXRXZWlnaHQoUUZvbnQ6OkV4dHJhTGlnaHQpOwogICAgICAgIGludGVyYWN0aW9uU3RyID0gaW50ZXJhY3Rpb25TdHIuc2ltcGxpZmllZCgpOwogICAgICAgIGF1dG8gdHlwZSA9IFV0aWxzOjp0b0VudW08bHJjOjphcGk6OmludGVyYWN0aW9uOjpUeXBlPihpbmRleAogICAgICAgICAgICAuZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpMYXN0SW50ZXJhY3Rpb25UeXBlKSkKICAgICAgICAgICAgLnZhbHVlPGludD4oKSk7CiAgICAgICAgaWYgKHR5cGUgPT0gbHJjOjphcGk6OmludGVyYWN0aW9uOjpUeXBlOjpDQUxMIHx8CiAgICAgICAgICAgIHR5cGUgPT0gbHJjOjphcGk6OmludGVyYWN0aW9uOjpUeXBlOjpDT05UQUNUKSB7CiAgICAgICAgICAgIGZvbnQuc2V0SXRhbGljKGZhbHNlKTsKICAgICAgICAgICAgZm9udC5zZXRCb2xkKGZhbHNlKTsKICAgICAgICAgICAgcGVuLnNldENvbG9yKFJpbmdUaGVtZTo6Z3JleV8uZGFya2VyKDE0MCkpOwogICAgICAgICAgICBwYWludGVyLT5zZXRQZW4ocGVuKTsKICAgICAgICAgICAgcGFpbnRlci0+c2V0Rm9udChmb250KTsKICAgICAgICAgICAgLy8gc3RyaXAgZW1vamlzIGlmIGl0J3MgYSBjYWxsL2NvbnRhY3QgdHlwZSBtZXNzYWdlCiAgICAgICAgICAgIFZlY3RvclVJbnQgZW1vamlsZXNzOwogICAgICAgICAgICBmb3IgKGF1dG8gdW5pY29kZSA6IGludGVyYWN0aW9uU3RyLnRvVWNzNCgpKSB7CiAgICAgICAgICAgICAgICBpZiAoISh1bmljb2RlID49IDB4MUYwMDAgJiYgdW5pY29kZSA8PSAweDFGRkZGKSkgewogICAgICAgICAgICAgICAgICAgIGVtb2ppbGVzcy5wdXNoX2JhY2sodW5pY29kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50ZXJhY3Rpb25TdHIgPSBRU3RyaW5nOjpmcm9tVWNzNCgmZW1vamlsZXNzLmF0KDApLCBlbW9qaWxlc3Muc2l6ZSgpKTsKICAgICAgICAgICAgLy8gcmVtb3ZlIGV2ZXJ5dGhpbiBhZnRlciAnY2FsbCcKICAgICAgICAgICAgYXV0byBpbmRleE9mQ2FsbFN0ciA9IGludGVyYWN0aW9uU3RyLmxhc3RJbmRleE9mKFFTdHJpbmcoImNhbGwiKSwgLTEsIFF0OjpDYXNlSW5zZW5zaXRpdmUpOwogICAgICAgICAgICBpZiAoaW5kZXhPZkNhbGxTdHIgIT0gLTEpIHsKICAgICAgICAgICAgICAgIGludGVyYWN0aW9uU3RyID0gaW50ZXJhY3Rpb25TdHIubGVmdChpbmRleE9mQ2FsbFN0ciArIDQpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUUZvbnQgZW1vamlNc2dGb250KFFTdHJpbmdMaXRlcmFsKCJTZWdvZSBVSSBFbW9qaSIpKTsKICAgICAgICAgICAgZW1vamlNc2dGb250LnNldEl0YWxpYyhmYWxzZSk7CiAgICAgICAgICAgIGVtb2ppTXNnRm9udC5zZXRCb2xkKGZhbHNlKTsKICAgICAgICAgICAgZW1vamlNc2dGb250LnNldFBvaW50U2l6ZShzY2FsaW5nUmF0aW8gPiAxLjAgPyBmb250U2l6ZV8gLSAyIDogZm9udFNpemVfKTsKICAgICAgICAgICAgcmVjdEluZm8yLnNldFRvcChyZWN0SW5mbzIudG9wKCkgLSA2KTsKICAgICAgICAgICAgcGFpbnRlci0+c2V0T3BhY2l0eSgwLjcpOwogICAgICAgICAgICBwYWludGVyLT5zZXRGb250KGVtb2ppTXNnRm9udCk7CiAgICAgICAgfQogICAgICAgIGludGVyYWN0aW9uU3RyID0gZm9udE1ldHJpY3MuZWxpZGVkVGV4dChpbnRlcmFjdGlvblN0ciwgUXQ6OkVsaWRlUmlnaHQsIHJlY3RJbmZvMi53aWR0aCgpKTsKICAgICAgICBwYWludGVyLT5kcmF3VGV4dChyZWN0SW5mbzIsIFF0OjpBbGlnblZDZW50ZXIgfCBRdDo6QWxpZ25SaWdodCwgaW50ZXJhY3Rpb25TdHIpOwogICAgICAgIHBhaW50ZXItPnJlc3RvcmUoKTsKICAgIH0KfQoKdm9pZApDb252ZXJzYXRpb25JdGVtRGVsZWdhdGU6OnBhaW50UmluZ0ludml0ZUNvbnZlcnNhdGlvbkl0ZW0oUVBhaW50ZXIqIHBhaW50ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRU3R5bGVPcHRpb25WaWV3SXRlbSYgb3B0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUVJlY3QmIHJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRTW9kZWxJbmRleCYgaW5kZXgpIGNvbnN0CnsKICAgIFFGb250IGZvbnQocGFpbnRlci0+Zm9udCgpKTsKICAgIFFQZW4gcGVuKHBhaW50ZXItPnBlbigpKTsKICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwoKICAgIGF1dG8gbGVmdE1hcmdpbiA9IGR4XyArIHNpemVJbWFnZV8gKyBkeF87CiAgICBhdXRvIHJpZ2h0TWFyZ2luID0gZHhfOwoKICAgIGF1dG8gc2NhbGluZ1JhdGlvID0gTWFpbldpbmRvdzo6aW5zdGFuY2UoKS5nZXRDdXJyZW50U2NhbGluZ1JhdGlvKCk7CiAgICBmb250LnNldFBvaW50U2l6ZShzY2FsaW5nUmF0aW8gPiAxLjAgPyBmb250U2l6ZV8gLSAyIDogZm9udFNpemVfKTsKCiAgICBpZiAob3B0aW9uLnN0YXRlICYgUVN0eWxlOjpTdGF0ZV9Nb3VzZU92ZXIpIHsKICAgICAgICBpZiAoc2NhbGluZ1JhdGlvID4gMS4wKSB7CiAgICAgICAgICAgIHJpZ2h0TWFyZ2luID0gaW5mb1RleHRXaWR0aF8gKyAxMiAtIGR4XyAqIDI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmlnaHRNYXJnaW4gPSBpbmZvVGV4dFdpZHRoXyAtIGR4XyAqIDI7CiAgICAgICAgfQogICAgfQoKICAgIGF1dG8gdG9wTWFyZ2luID0gNDsKICAgIGF1dG8gYm90dG9tTWFyZ2luID0gODsKCiAgICBRUmVjdCByZWN0TmFtZTEocmVjdC5sZWZ0KCkgKyBsZWZ0TWFyZ2luLAogICAgICAgIHJlY3QudG9wKCkgKyB0b3BNYXJnaW4sCiAgICAgICAgcmVjdC53aWR0aCgpIC0gbGVmdE1hcmdpbiAtIHJpZ2h0TWFyZ2luLAogICAgICAgIHJlY3QuaGVpZ2h0KCkgLyAyIC0gMik7CgogICAgUVJlY3QgcmVjdE5hbWUyKHJlY3ROYW1lMS5sZWZ0KCksCiAgICAgICAgcmVjdE5hbWUxLnRvcCgpICsgcmVjdE5hbWUxLmhlaWdodCgpLAogICAgICAgIHJlY3ROYW1lMS53aWR0aCgpLAogICAgICAgIHJlY3ROYW1lMS5oZWlnaHQoKSAtIGJvdHRvbU1hcmdpbik7CgogICAgUUZvbnRNZXRyaWNzIGZvbnRNZXRyaWNzKGZvbnQpOwoKICAgIC8vIFRoZSBuYW1lIGlzIGRpc3BsYXllZCBhdCB0aGUgYXZhdGFyJ3MgcmlnaHQKICAgIFFTdHJpbmcgbmFtZVN0ciA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6RGlzcGxheU5hbWUpKS52YWx1ZTxRU3RyaW5nPigpOwogICAgaWYgKCFuYW1lU3RyLmlzTnVsbCgpKSB7CiAgICAgICAgZm9udC5zZXRJdGFsaWMoZmFsc2UpOwogICAgICAgIGZvbnQuc2V0Qm9sZChmYWxzZSk7CiAgICAgICAgcGVuLnNldENvbG9yKFJpbmdUaGVtZTo6bGlnaHRCbGFja18pOwogICAgICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwogICAgICAgIHBhaW50ZXItPnNldEZvbnQoZm9udCk7CiAgICAgICAgUVN0cmluZyBlbGlkZWROYW1lU3RyID0gZm9udE1ldHJpY3MuZWxpZGVkVGV4dChuYW1lU3RyLCBRdDo6RWxpZGVSaWdodCwgcmVjdE5hbWUxLndpZHRoKCkpOwogICAgICAgIHBhaW50ZXItPmRyYXdUZXh0KHJlY3ROYW1lMSwgUXQ6OkFsaWduVkNlbnRlciB8IFF0OjpBbGlnbkxlZnQsIGVsaWRlZE5hbWVTdHIpOwogICAgfQoKICAgIC8vIERpc3BsYXkgdGhlIElEIHVuZGVyIHRoZSBuYW1lCiAgICBRU3RyaW5nIGlkU3RyID0gaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpEaXNwbGF5SUQpKS52YWx1ZTxRU3RyaW5nPigpOwogICAgaWYgKGlkU3RyICE9IG5hbWVTdHIgJiYgIWlkU3RyLmlzTnVsbCgpKSB7CiAgICAgICAgZm9udC5zZXRJdGFsaWMoZmFsc2UpOwogICAgICAgIGZvbnQuc2V0Qm9sZChmYWxzZSk7CiAgICAgICAgcGVuLnNldENvbG9yKFJpbmdUaGVtZTo6Z3JleV8pOwogICAgICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwogICAgICAgIHBhaW50ZXItPnNldEZvbnQoZm9udCk7CiAgICAgICAgaWRTdHIgPSBmb250TWV0cmljcy5lbGlkZWRUZXh0KGlkU3RyLCBRdDo6RWxpZGVSaWdodCwgcmVjdE5hbWUyLndpZHRoKCkpOwogICAgICAgIHBhaW50ZXItPmRyYXdUZXh0KHJlY3ROYW1lMiwgUXQ6OkFsaWduVkNlbnRlciB8IFF0OjpBbGlnbkxlZnQsIGlkU3RyKTsKICAgIH0KfQoKdm9pZApDb252ZXJzYXRpb25JdGVtRGVsZWdhdGU6OnBhaW50U0lQQ29udmVyc2F0aW9uSXRlbShRUGFpbnRlciogcGFpbnRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUVN0eWxlT3B0aW9uVmlld0l0ZW0mIG9wdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUU1vZGVsSW5kZXgmIGluZGV4KSBjb25zdAp7CiAgICBRX1VOVVNFRChwYWludGVyKTsKICAgIFFfVU5VU0VEKG9wdGlvbik7CiAgICBRX1VOVVNFRChpbmRleCk7Cn0K