LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKEMpIDIwMTUtMjAxNyBieSBTYXZvaXItZmFpcmUgTGludXggICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIEF1dGhvcjogRWRyaWMgTGFkZW50IE1pbGFyZXQgPGVkcmljLmxhZGVudC1taWxhcmV0QHNhdm9pcmZhaXJlbGludXguY29tPioKICogQXV0aG9yOiBBbmRyZWFzIFRyYWN6eWsgPGFuZHJlYXMudHJhY3p5a0BzYXZvaXJmYWlyZWxpbnV4LmNvbT4gICAgICAgICAgKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5ICAgICoKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgICAgKgogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvciAgICAgICAqCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgICAgICAgICAqCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mICAgICAgICAgICoKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSAgICAgICAgICAgKgogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgICAgICAgKgogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4gICAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJjb252ZXJzYXRpb25pdGVtZGVsZWdhdGUuaCIKCiNpbmNsdWRlIDxRQXBwbGljYXRpb24+CiNpbmNsdWRlIDxRUGFpbnRlcj4KI2luY2x1ZGUgPFFQaXhtYXA+CgovLyBDbGllbnQKI2luY2x1ZGUgInNtYXJ0bGlzdG1vZGVsLmgiCiNpbmNsdWRlICJyaW5ndGhlbWV1dGlscy5oIgojaW5jbHVkZSAidXRpbHMuaCIKI2luY2x1ZGUgImxyY2luc3RhbmNlLmgiCgojaW5jbHVkZSA8Y2lzbzY0Nj4KCkNvbnZlcnNhdGlvbkl0ZW1EZWxlZ2F0ZTo6Q29udmVyc2F0aW9uSXRlbURlbGVnYXRlKFFPYmplY3QqIHBhcmVudCkKICAgIDogUUl0ZW1EZWxlZ2F0ZShwYXJlbnQpCnsKfQoKdm9pZApDb252ZXJzYXRpb25JdGVtRGVsZWdhdGU6OnBhaW50KFFQYWludGVyKiBwYWludGVyCiAgICAgICAgICAgICAgICAgICAgICAgICwgY29uc3QgUVN0eWxlT3B0aW9uVmlld0l0ZW0mIG9wdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAsIGNvbnN0IFFNb2RlbEluZGV4JiBpbmRleAogICAgICAgICAgICAgICAgICAgICAgICApIGNvbnN0CnsKICAgIFFTdHlsZU9wdGlvblZpZXdJdGVtIG9wdChvcHRpb24pOwogICAgcGFpbnRlci0+c2V0UmVuZGVySGludChRUGFpbnRlcjo6QW50aWFsaWFzaW5nLCB0cnVlKTsKCiAgICAvLyBOb3QgaGF2aW5nIGZvY3VzIHJlbW92ZXMgZG90dGVkIGxpbmVzIGFyb3VuZCB0aGUgaXRlbQogICAgaWYgKG9wdC5zdGF0ZSAmIFFTdHlsZTo6U3RhdGVfSGFzRm9jdXMpCiAgICAgICAgb3B0LnN0YXRlIF49IFFTdHlsZTo6U3RhdGVfSGFzRm9jdXM7CgogICAgYXV0byBpc0NvbnRleHRNZW51T3BlbiA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6Q29udGV4dE1lbnVPcGVuKSkudmFsdWU8Ym9vbD4oKTsKICAgIGJvb2wgc2VsZWN0ZWQgPSBmYWxzZTsKICAgIGlmIChvcHRpb24uc3RhdGUgJiBRU3R5bGU6OlN0YXRlX1NlbGVjdGVkKSB7CiAgICAgICAgc2VsZWN0ZWQgPSB0cnVlOwogICAgICAgIG9wdC5zdGF0ZSBePSBRU3R5bGU6OlN0YXRlX1NlbGVjdGVkOwogICAgfSBlbHNlIGlmICghaXNDb250ZXh0TWVudU9wZW4pIHsKICAgICAgICBoaWdobGlnaHRNYXBfW2luZGV4LnJvdygpXSA9IG9wdGlvbi5zdGF0ZSAmIFFTdHlsZTo6U3RhdGVfTW91c2VPdmVyOwogICAgfQoKICAgIC8vIE9uZSBkb2VzIG5vdCBzaW1wbHkga2VlcCB0aGUgaGlnaGxpZ2h0ZWQgc3RhdGUgZHJhd24gd2hlbiB0aGUgY29udGV4dAogICAgLy8gbWVudSBpcyBvcGVuhQogICAgYXV0byByb3dIaWdobGlnaHQgPSBoaWdobGlnaHRNYXBfLmZpbmQoaW5kZXgucm93KCkpOwogICAgaWYgKHNlbGVjdGVkKSB7CiAgICAgICAgcGFpbnRlci0+ZmlsbFJlY3Qob3B0aW9uLnJlY3QsIFJpbmdUaGVtZTo6c21hcnRsaXN0U2VsZWN0aW9uXyk7CiAgICB9IGVsc2UgaWYgKHJvd0hpZ2hsaWdodCAhPSBoaWdobGlnaHRNYXBfLmVuZCgpICYmICgqcm93SGlnaGxpZ2h0KS5zZWNvbmQpIHsKICAgICAgICBwYWludGVyLT5maWxsUmVjdChvcHRpb24ucmVjdCwgUmluZ1RoZW1lOjpzbWFydGxpc3RIaWdobGlnaHRfKTsKICAgIH0KCiAgICBRUmVjdCAmcmVjdCA9IG9wdC5yZWN0OwoKICAgIC8vIEF2YXRhciBkcmF3aW5nCiAgICBvcHQuZGVjb3JhdGlvblNpemUgPSBRU2l6ZShzaXplSW1hZ2VfLCBzaXplSW1hZ2VfKTsKICAgIG9wdC5kZWNvcmF0aW9uUG9zaXRpb24gPSBRU3R5bGVPcHRpb25WaWV3SXRlbTo6TGVmdDsKICAgIG9wdC5kZWNvcmF0aW9uQWxpZ25tZW50ID0gUXQ6OkFsaWduQ2VudGVyOwoKICAgIFFSZWN0IHJlY3RBdmF0YXIoZHhfICsgcmVjdC5sZWZ0KCksIHJlY3QudG9wKCkgKyBkeV8sIHNpemVJbWFnZV8sIHNpemVJbWFnZV8pOwogICAgZHJhd0RlY29yYXRpb24ocGFpbnRlciwgb3B0LCByZWN0QXZhdGFyLAogICAgICAgICAgICAgICAgICAgUVBpeG1hcDo6ZnJvbUltYWdlKGluZGV4LmRhdGEoUXQ6OkRlY29yYXRpb25Sb2xlKS52YWx1ZTxRSW1hZ2U+KCkpCiAgICAgICAgICAgICAgICAgICAuc2NhbGVkKHNpemVJbWFnZV8sIHNpemVJbWFnZV8sIFF0OjpLZWVwQXNwZWN0UmF0aW8sIFF0OjpTbW9vdGhUcmFuc2Zvcm1hdGlvbikpOwoKICAgIFFGb250IGZvbnQocGFpbnRlci0+Zm9udCgpKTsKCiAgICAvLyBJZiB0aGVyZSdzIHVucmVhZCBtZXNzYWdlcywgYSBtZXNzYWdlIGNvdW50IGlzIGRpc3BsYXllZAogICAgaWYgKGF1dG8gbWVzc2FnZUNvdW50ID0gaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpVbnJlYWRNZXNzYWdlc0NvdW50KSkudG9JbnQoKSkgewogICAgICAgIFFTdHJpbmcgbWVzc2FnZUNvdW50VGV4dCA9IChtZXNzYWdlQ291bnQgPiA5KSA/ICI5KyIgOiBRU3RyaW5nOjpudW1iZXIobWVzc2FnZUNvdW50KTsKICAgICAgICBxcmVhbCBmb250U2l6ZSA9IG1lc3NhZ2VDb3VudFRleHQuY291bnQoKSA+IDEgPyA3IDogODsKICAgICAgICBmb250LnNldFBvaW50U2l6ZShmb250U2l6ZSk7CgogICAgICAgIC8vIGVsbGlwc2UKICAgICAgICBRUGFpbnRlclBhdGggZWxsaXBzZTsKICAgICAgICBxcmVhbCBlbGxpcHNlSGVpZ2h0ID0gc2l6ZUltYWdlXyAvIDY7CiAgICAgICAgcXJlYWwgZWxsaXBzZVdpZHRoID0gZWxsaXBzZUhlaWdodDsKICAgICAgICBRUG9pbnRGIGVsbGlwc2VDZW50ZXIocmVjdEF2YXRhci5yaWdodCgpIC0gZWxsaXBzZVdpZHRoLCByZWN0QXZhdGFyLnRvcCgpICsgZWxsaXBzZUhlaWdodCArIDEpOwogICAgICAgIFFSZWN0IGVsbGlwc2VSZWN0KGVsbGlwc2VDZW50ZXIueCgpIC0gZWxsaXBzZVdpZHRoLCBlbGxpcHNlQ2VudGVyLnkoKSAtIGVsbGlwc2VIZWlnaHQsCiAgICAgICAgICAgIGVsbGlwc2VXaWR0aCAqIDIsIGVsbGlwc2VIZWlnaHQgKiAyKTsKICAgICAgICBlbGxpcHNlLmFkZFJvdW5kZWRSZWN0KGVsbGlwc2VSZWN0LCBlbGxpcHNlV2lkdGgsIGVsbGlwc2VIZWlnaHQpOwogICAgICAgIHBhaW50ZXItPmZpbGxQYXRoKGVsbGlwc2UsIFJpbmdUaGVtZTo6bm90aWZpY2F0aW9uUmVkXyk7CgogICAgICAgIC8vIHRleHQKICAgICAgICBwYWludGVyLT5zZXRQZW4oUXQ6OndoaXRlKTsKICAgICAgICBwYWludGVyLT5zZXRPcGFjaXR5KDEpOwogICAgICAgIHBhaW50ZXItPnNldEZvbnQoZm9udCk7CiAgICAgICAgZWxsaXBzZVJlY3Quc2V0VG9wKGVsbGlwc2VSZWN0LnRvcCgpIC0gMik7CiAgICAgICAgcGFpbnRlci0+ZHJhd1RleHQoZWxsaXBzZVJlY3QsIFF0OjpBbGlnbkNlbnRlciwgbWVzc2FnZUNvdW50VGV4dCk7CiAgICB9CgogICAgLy8gUHJlc2VuY2UgaW5kaWNhdG9yCiAgICBpZiAoaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpQcmVzZW5jZSkpLnZhbHVlPGJvb2w+KCkpIHsKICAgICAgICBxcmVhbCByYWRpdXMgPSBzaXplSW1hZ2VfIC8gNjsKICAgICAgICBRUGFpbnRlclBhdGggb3V0ZXJDaXJjbGUsIGlubmVyQ2lyY2xlOwogICAgICAgIFFQb2ludEYgY2VudGVyKHJlY3RBdmF0YXIucmlnaHQoKSAtIHJhZGl1cywgKHJlY3RBdmF0YXIuYm90dG9tKCkgLSByYWRpdXMpICsgMSk7CiAgICAgICAgcXJlYWwgb3V0ZXJDUmFkaXVzID0gcmFkaXVzOwogICAgICAgIHFyZWFsIGlubmVyQ1JhZGl1cyA9IG91dGVyQ1JhZGl1cyAqIDAuNzU7CiAgICAgICAgb3V0ZXJDaXJjbGUuYWRkRWxsaXBzZShjZW50ZXIsIG91dGVyQ1JhZGl1cywgb3V0ZXJDUmFkaXVzKTsKICAgICAgICBpbm5lckNpcmNsZS5hZGRFbGxpcHNlKGNlbnRlciwgaW5uZXJDUmFkaXVzLCBpbm5lckNSYWRpdXMpOwogICAgICAgIHBhaW50ZXItPmZpbGxQYXRoKG91dGVyQ2lyY2xlLCBRdDo6d2hpdGUpOwogICAgICAgIHBhaW50ZXItPmZpbGxQYXRoKGlubmVyQ2lyY2xlLCBSaW5nVGhlbWU6OnByZXNlbmNlR3JlZW5fKTsKICAgIH0KCiAgICB1c2luZyBuYW1lc3BhY2UgbHJjOjphcGk7CiAgICBhdXRvIHR5cGUgPSBVdGlsczo6dG9FbnVtPHByb2ZpbGU6OlR5cGU+KAogICAgICAgIGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6Q29udGFjdFR5cGUpKS52YWx1ZTxpbnQ+KCkKICAgICAgICApOwogICAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIHByb2ZpbGU6OlR5cGU6OlJJTkc6CiAgICBjYXNlIHByb2ZpbGU6OlR5cGU6OlRFTVBPUkFSWToKICAgICAgICBwYWludFJpbmdDb252ZXJzYXRpb25JdGVtKHBhaW50ZXIsIG9wdGlvbiwgcmVjdCwgaW5kZXgpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBwcm9maWxlOjpUeXBlOjpQRU5ESU5HOgogICAgICAgIHBhaW50UmluZ0ludml0ZUNvbnZlcnNhdGlvbkl0ZW0ocGFpbnRlciwgb3B0aW9uLCByZWN0LCBpbmRleCk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIHByb2ZpbGU6OlR5cGU6OlNJUDoKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcGFpbnRSaW5nQ29udmVyc2F0aW9uSXRlbShwYWludGVyLCBvcHRpb24sIHJlY3QsIGluZGV4KTsKICAgICAgICBicmVhazsKICAgIH0KfQoKUVNpemUKQ29udmVyc2F0aW9uSXRlbURlbGVnYXRlOjpzaXplSGludChjb25zdCBRU3R5bGVPcHRpb25WaWV3SXRlbSYgb3B0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFFNb2RlbEluZGV4JiBpbmRleCkgY29uc3QKewogICAgUV9VTlVTRUQob3B0aW9uKTsKICAgIFFfVU5VU0VEKGluZGV4KTsKICAgIHJldHVybiBRU2l6ZSgwLCBjZWxsSGVpZ2h0Xyk7Cn0KCnZvaWQKQ29udmVyc2F0aW9uSXRlbURlbGVnYXRlOjpwYWludFJpbmdDb252ZXJzYXRpb25JdGVtKFFQYWludGVyKiBwYWludGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUVN0eWxlT3B0aW9uVmlld0l0ZW0mIG9wdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFFSZWN0JiByZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUU1vZGVsSW5kZXgmIGluZGV4KSBjb25zdAp7CiAgICBRX1VOVVNFRChvcHRpb24pOwogICAgUUZvbnQgZm9udChwYWludGVyLT5mb250KCkpOwogICAgZm9udC5zZXRQb2ludFNpemUoZm9udFNpemVfKTsKICAgIFFQZW4gcGVuKHBhaW50ZXItPnBlbigpKTsKICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwoKICAgIGF1dG8gbGVmdE1hcmdpbiA9IGR4XyArIHNpemVJbWFnZV8gKyBkeF8gLyAyOwogICAgYXV0byByaWdodE1hcmdpbiA9IGR4XzsKICAgIGF1dG8gdG9wTWFyZ2luID0gMDsKICAgIGF1dG8gYm90dG9tTWFyZ2luID0gMTI7CgogICAgUVJlY3QgcmVjdE5hbWUxKHJlY3QubGVmdCgpICsgbGVmdE1hcmdpbiwKICAgICAgICAgICAgICAgICAgICByZWN0LnRvcCgpICsgdG9wTWFyZ2luLAogICAgICAgICAgICAgICAgICAgIHJlY3Qud2lkdGgoKSAtIGxlZnRNYXJnaW4gLSBpbmZvVGV4dFdpZHRoXywKICAgICAgICAgICAgICAgICAgICByZWN0LmhlaWdodCgpIC8gMik7CgogICAgUVJlY3QgcmVjdE5hbWUyKHJlY3ROYW1lMS5sZWZ0KCksCiAgICAgICAgICAgICAgICAgICAgcmVjdE5hbWUxLnRvcCgpICsgcmVjdE5hbWUxLmhlaWdodCgpLAogICAgICAgICAgICAgICAgICAgIHJlY3ROYW1lMS53aWR0aCgpLAogICAgICAgICAgICAgICAgICAgIHJlY3ROYW1lMS5oZWlnaHQoKSAtIGJvdHRvbU1hcmdpbik7CgogICAgUVJlY3QgcmVjdEluZm8xKHJlY3ROYW1lMS5sZWZ0KCkgKyByZWN0TmFtZTEud2lkdGgoKSwKICAgICAgICAgICAgICAgICAgICByZWN0LnRvcCgpICsgdG9wTWFyZ2luLAogICAgICAgICAgICAgICAgICAgIGluZm9UZXh0V2lkdGhfIC0gcmlnaHRNYXJnaW4sCiAgICAgICAgICAgICAgICAgICAgcmVjdC5oZWlnaHQoKSAvIDIpOwoKICAgIFFSZWN0IHJlY3RJbmZvMihyZWN0SW5mbzEubGVmdCgpLAogICAgICAgICAgICAgICAgICAgIHJlY3RJbmZvMS50b3AoKSArIHJlY3RJbmZvMS5oZWlnaHQoKSwKICAgICAgICAgICAgICAgICAgICByZWN0SW5mbzEud2lkdGgoKSwKICAgICAgICAgICAgICAgICAgICByZWN0SW5mbzEuaGVpZ2h0KCkgLSBib3R0b21NYXJnaW4pOwoKICAgIFFGb250TWV0cmljcyBmb250TWV0cmljcyhmb250KTsKCiAgICAvLyBUaGUgbmFtZSBpcyBkaXNwbGF5ZWQgYXQgdGhlIGF2YXRhcidzIHJpZ2h0CiAgICBRU3RyaW5nIG5hbWVTdHIgPSBpbmRleC5kYXRhKHN0YXRpY19jYXN0PGludD4oU21hcnRMaXN0TW9kZWw6OlJvbGU6OkRpc3BsYXlOYW1lKSkudmFsdWU8UVN0cmluZz4oKTsKICAgIGlmICghbmFtZVN0ci5pc051bGwoKSkgewogICAgICAgIGZvbnQuc2V0SXRhbGljKGZhbHNlKTsKICAgICAgICBmb250LnNldEJvbGQodHJ1ZSk7CiAgICAgICAgcGVuLnNldENvbG9yKFJpbmdUaGVtZTo6bGlnaHRCbGFja18pOwogICAgICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwogICAgICAgIHBhaW50ZXItPnNldEZvbnQoZm9udCk7CiAgICAgICAgUVN0cmluZyBlbGlkZWROYW1lU3RyID0gZm9udE1ldHJpY3MuZWxpZGVkVGV4dChuYW1lU3RyLCBRdDo6RWxpZGVSaWdodCwgcmVjdE5hbWUxLndpZHRoKCkpOwogICAgICAgIHBhaW50ZXItPmRyYXdUZXh0KHJlY3ROYW1lMSwgUXQ6OkFsaWduVkNlbnRlciB8IFF0OjpBbGlnbkxlZnQsIGVsaWRlZE5hbWVTdHIpOwogICAgfQoKICAgIC8vIERpc3BsYXkgdGhlIElEIHVuZGVyIHRoZSBuYW1lCiAgICBRU3RyaW5nIGlkU3RyID0gaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpEaXNwbGF5SUQpKS52YWx1ZTxRU3RyaW5nPigpOwogICAgaWYgKGlkU3RyICE9IG5hbWVTdHIgJiYgIWlkU3RyLmlzTnVsbCgpKSB7CiAgICAgICAgZm9udC5zZXRJdGFsaWMoZmFsc2UpOwogICAgICAgIGZvbnQuc2V0Qm9sZChmYWxzZSk7CiAgICAgICAgcGVuLnNldENvbG9yKFJpbmdUaGVtZTo6Z3JleV8pOwogICAgICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwogICAgICAgIHBhaW50ZXItPnNldEZvbnQoZm9udCk7CiAgICAgICAgaWRTdHIgPSBmb250TWV0cmljcy5lbGlkZWRUZXh0KGlkU3RyLCBRdDo6RWxpZGVSaWdodCwgcmVjdE5hbWUyLndpZHRoKCkpOwogICAgICAgIHBhaW50ZXItPmRyYXdUZXh0KHJlY3ROYW1lMiwgUXQ6OkFsaWduVkNlbnRlciB8IFF0OjpBbGlnbkxlZnQsIGlkU3RyKTsKICAgIH0KCiAgICAvLyB0b3AtcmlnaHQ6IGxhc3QgaW50ZXJhY3Rpb24gZGF0ZS90aW1lCiAgICBRU3RyaW5nIGxhc3RVc2VkU3RyID0gaW5kZXguZGF0YShzdGF0aWNfY2FzdDxpbnQ+KFNtYXJ0TGlzdE1vZGVsOjpSb2xlOjpMYXN0SW50ZXJhY3Rpb25EYXRlKSkudmFsdWU8UVN0cmluZz4oKTsKICAgIGlmICghbGFzdFVzZWRTdHIuaXNOdWxsKCkpIHsKICAgICAgICBmb250LnNldEl0YWxpYyhmYWxzZSk7CiAgICAgICAgZm9udC5zZXRCb2xkKGZhbHNlKTsKICAgICAgICBwZW4uc2V0Q29sb3IoUmluZ1RoZW1lOjpncmV5Xyk7CiAgICAgICAgcGFpbnRlci0+c2V0UGVuKHBlbik7CiAgICAgICAgcGFpbnRlci0+c2V0Rm9udChmb250KTsKICAgICAgICBsYXN0VXNlZFN0ciA9IGZvbnRNZXRyaWNzLmVsaWRlZFRleHQobGFzdFVzZWRTdHIsIFF0OjpFbGlkZVJpZ2h0LCByZWN0SW5mbzEud2lkdGgoKSk7CiAgICAgICAgcGFpbnRlci0+ZHJhd1RleHQocmVjdEluZm8xLCBRdDo6QWxpZ25WQ2VudGVyIHwgUXQ6OkFsaWduUmlnaHQsIGxhc3RVc2VkU3RyKTsKICAgIH0KCiAgICAvLyBib3R0b20tcmlnaHQ6IGxhc3QgaW50ZXJhY3Rpb24gc25pcHBldAogICAgUVN0cmluZyBpbnRlcmFjdGlvblN0ciA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6TGFzdEludGVyYWN0aW9uKSkudmFsdWU8UVN0cmluZz4oKTsKICAgIGlmICghaW50ZXJhY3Rpb25TdHIuaXNOdWxsKCkpIHsKICAgICAgICBwYWludGVyLT5zYXZlKCk7CiAgICAgICAgaW50ZXJhY3Rpb25TdHIgPSBpbnRlcmFjdGlvblN0ci5zaW1wbGlmaWVkKCk7CiAgICAgICAgYXV0byB0eXBlID0gVXRpbHM6OnRvRW51bTxscmM6OmFwaTo6aW50ZXJhY3Rpb246OlR5cGU+KGluZGV4CiAgICAgICAgICAgIC5kYXRhKHN0YXRpY19jYXN0PGludD4oU21hcnRMaXN0TW9kZWw6OlJvbGU6Okxhc3RJbnRlcmFjdGlvblR5cGUpKQogICAgICAgICAgICAudmFsdWU8aW50PigpKTsKICAgICAgICBpZiAodHlwZSA9PSBscmM6OmFwaTo6aW50ZXJhY3Rpb246OlR5cGU6OkNBTEwgfHwKICAgICAgICAgICAgdHlwZSA9PSBscmM6OmFwaTo6aW50ZXJhY3Rpb246OlR5cGU6OkNPTlRBQ1QpIHsKICAgICAgICAgICAgZm9udC5zZXRJdGFsaWMoZmFsc2UpOwogICAgICAgICAgICBmb250LnNldEJvbGQoZmFsc2UpOwogICAgICAgICAgICBwZW4uc2V0Q29sb3IoUmluZ1RoZW1lOjpncmV5Xy5kYXJrZXIoMTQwKSk7CiAgICAgICAgICAgIHBhaW50ZXItPnNldFBlbihwZW4pOwogICAgICAgICAgICBwYWludGVyLT5zZXRGb250KGZvbnQpOwogICAgICAgICAgICAvLyBzdHJpcCBlbW9qaXMgaWYgaXQncyBhIGNhbGwvY29udGFjdCB0eXBlIG1lc3NhZ2UKICAgICAgICAgICAgVmVjdG9yVUludCBlbW9qaWxlc3M7CiAgICAgICAgICAgIGZvciAoYXV0byB1bmljb2RlIDogaW50ZXJhY3Rpb25TdHIudG9VY3M0KCkpIHsKICAgICAgICAgICAgICAgIGlmICghKHVuaWNvZGUgPj0gMHgxRjAwMCAmJiB1bmljb2RlIDw9IDB4MUZGRkYpKSB7CiAgICAgICAgICAgICAgICAgICAgZW1vamlsZXNzLnB1c2hfYmFjayh1bmljb2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpbnRlcmFjdGlvblN0ciA9IFFTdHJpbmc6OmZyb21VY3M0KCZlbW9qaWxlc3MuYXQoMCksIGVtb2ppbGVzcy5zaXplKCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFFGb250IGVtb2ppTXNnRm9udChRU3RyaW5nTGl0ZXJhbCgiU2Vnb2UgVUkgRW1vamkiKSk7CiAgICAgICAgICAgIGVtb2ppTXNnRm9udC5zZXRJdGFsaWMoZmFsc2UpOwogICAgICAgICAgICBlbW9qaU1zZ0ZvbnQuc2V0Qm9sZChmYWxzZSk7CiAgICAgICAgICAgIGVtb2ppTXNnRm9udC5zZXRQb2ludFNpemUoZm9udFNpemVfKTsKICAgICAgICAgICAgcGFpbnRlci0+c2V0T3BhY2l0eSgwLjcpOwogICAgICAgICAgICBwYWludGVyLT5zZXRGb250KGVtb2ppTXNnRm9udCk7CiAgICAgICAgfQogICAgICAgIGludGVyYWN0aW9uU3RyID0gZm9udE1ldHJpY3MuZWxpZGVkVGV4dChpbnRlcmFjdGlvblN0ciwgUXQ6OkVsaWRlUmlnaHQsIHJlY3RJbmZvMi53aWR0aCgpKTsKICAgICAgICBwYWludGVyLT5kcmF3VGV4dChyZWN0SW5mbzIsIFF0OjpBbGlnblZDZW50ZXIgfCBRdDo6QWxpZ25SaWdodCwgaW50ZXJhY3Rpb25TdHIpOwogICAgICAgIHBhaW50ZXItPnJlc3RvcmUoKTsKICAgIH0KfQoKdm9pZApDb252ZXJzYXRpb25JdGVtRGVsZWdhdGU6OnBhaW50UmluZ0ludml0ZUNvbnZlcnNhdGlvbkl0ZW0oUVBhaW50ZXIqIHBhaW50ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRU3R5bGVPcHRpb25WaWV3SXRlbSYgb3B0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUVJlY3QmIHJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRTW9kZWxJbmRleCYgaW5kZXgpIGNvbnN0CnsKICAgIFFGb250IGZvbnQocGFpbnRlci0+Zm9udCgpKTsKICAgIGZvbnQuc2V0UG9pbnRTaXplKGZvbnRTaXplXyk7CiAgICBRUGVuIHBlbihwYWludGVyLT5wZW4oKSk7CiAgICBwYWludGVyLT5zZXRQZW4ocGVuKTsKCiAgICBhdXRvIGxlZnRNYXJnaW4gPSBkeF8gKyBzaXplSW1hZ2VfICsgZHhfIC8gMjsKICAgIGF1dG8gcmlnaHRNYXJnaW4gPSBkeF87CiAgICBpZiAob3B0aW9uLnN0YXRlICYgUVN0eWxlOjpTdGF0ZV9Nb3VzZU92ZXIpIHsKICAgICAgICByaWdodE1hcmdpbiA9IGluZm9UZXh0V2lkdGhfIC0gZHhfICogMjsKICAgIH0KICAgIGF1dG8gdG9wTWFyZ2luID0gMDsKICAgIGF1dG8gYm90dG9tTWFyZ2luID0gMTI7CgogICAgUVJlY3QgcmVjdE5hbWUxKHJlY3QubGVmdCgpICsgbGVmdE1hcmdpbiwKICAgICAgICByZWN0LnRvcCgpICsgdG9wTWFyZ2luLAogICAgICAgIHJlY3Qud2lkdGgoKSAtIGxlZnRNYXJnaW4gLSByaWdodE1hcmdpbiwKICAgICAgICByZWN0LmhlaWdodCgpIC8gMik7CgogICAgUVJlY3QgcmVjdE5hbWUyKHJlY3ROYW1lMS5sZWZ0KCksCiAgICAgICAgcmVjdE5hbWUxLnRvcCgpICsgcmVjdE5hbWUxLmhlaWdodCgpLAogICAgICAgIHJlY3ROYW1lMS53aWR0aCgpLAogICAgICAgIHJlY3ROYW1lMS5oZWlnaHQoKSAtIGJvdHRvbU1hcmdpbik7CgogICAgUUZvbnRNZXRyaWNzIGZvbnRNZXRyaWNzKGZvbnQpOwoKICAgIC8vIFRoZSBuYW1lIGlzIGRpc3BsYXllZCBhdCB0aGUgYXZhdGFyJ3MgcmlnaHQKICAgIFFTdHJpbmcgbmFtZVN0ciA9IGluZGV4LmRhdGEoc3RhdGljX2Nhc3Q8aW50PihTbWFydExpc3RNb2RlbDo6Um9sZTo6RGlzcGxheU5hbWUpKS52YWx1ZTxRU3RyaW5nPigpOwogICAgaWYgKCFuYW1lU3RyLmlzTnVsbCgpKSB7CiAgICAgICAgZm9udC5zZXRJdGFsaWMoZmFsc2UpOwogICAgICAgIGZvbnQuc2V0Qm9sZCh0cnVlKTsKICAgICAgICBwZW4uc2V0Q29sb3IoUmluZ1RoZW1lOjpsaWdodEJsYWNrXyk7CiAgICAgICAgcGFpbnRlci0+c2V0UGVuKHBlbik7CiAgICAgICAgcGFpbnRlci0+c2V0Rm9udChmb250KTsKICAgICAgICBRU3RyaW5nIGVsaWRlZE5hbWVTdHIgPSBmb250TWV0cmljcy5lbGlkZWRUZXh0KG5hbWVTdHIsIFF0OjpFbGlkZVJpZ2h0LCByZWN0TmFtZTEud2lkdGgoKSk7CiAgICAgICAgcGFpbnRlci0+ZHJhd1RleHQocmVjdE5hbWUxLCBRdDo6QWxpZ25WQ2VudGVyIHwgUXQ6OkFsaWduTGVmdCwgZWxpZGVkTmFtZVN0cik7CiAgICB9CgogICAgLy8gRGlzcGxheSB0aGUgSUQgdW5kZXIgdGhlIG5hbWUKICAgIFFTdHJpbmcgaWRTdHIgPSBpbmRleC5kYXRhKHN0YXRpY19jYXN0PGludD4oU21hcnRMaXN0TW9kZWw6OlJvbGU6OkRpc3BsYXlJRCkpLnZhbHVlPFFTdHJpbmc+KCk7CiAgICBpZiAoaWRTdHIgIT0gbmFtZVN0ciAmJiAhaWRTdHIuaXNOdWxsKCkpIHsKICAgICAgICBmb250LnNldEl0YWxpYyhmYWxzZSk7CiAgICAgICAgZm9udC5zZXRCb2xkKGZhbHNlKTsKICAgICAgICBwZW4uc2V0Q29sb3IoUmluZ1RoZW1lOjpncmV5Xyk7CiAgICAgICAgcGFpbnRlci0+c2V0UGVuKHBlbik7CiAgICAgICAgcGFpbnRlci0+c2V0Rm9udChmb250KTsKICAgICAgICBpZFN0ciA9IGZvbnRNZXRyaWNzLmVsaWRlZFRleHQoaWRTdHIsIFF0OjpFbGlkZVJpZ2h0LCByZWN0TmFtZTIud2lkdGgoKSk7CiAgICAgICAgcGFpbnRlci0+ZHJhd1RleHQocmVjdE5hbWUyLCBRdDo6QWxpZ25WQ2VudGVyIHwgUXQ6OkFsaWduTGVmdCwgaWRTdHIpOwogICAgfQp9Cgp2b2lkCkNvbnZlcnNhdGlvbkl0ZW1EZWxlZ2F0ZTo6cGFpbnRTSVBDb252ZXJzYXRpb25JdGVtKFFQYWludGVyKiBwYWludGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRU3R5bGVPcHRpb25WaWV3SXRlbSYgb3B0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBRTW9kZWxJbmRleCYgaW5kZXgpIGNvbnN0CnsKICAgIFFfVU5VU0VEKHBhaW50ZXIpOwogICAgUV9VTlVTRUQob3B0aW9uKTsKICAgIFFfVU5VU0VEKGluZGV4KTsKfQo=