LyoKICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIFN1biBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBTdW4gaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiwgNDE1MCBOZXR3b3JrIENpcmNsZSwgU2FudGEgQ2xhcmEsCiAqIENBIDk1MDU0IFVTQSBvciB2aXNpdCB3d3cuc3VuLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yCiAqIGhhdmUgYW55IHF1ZXN0aW9ucy4KICovCgovLyBUaGlzIGZpbGUgaXMgYXZhaWxhYmxlIHVuZGVyIGFuZCBnb3Zlcm5lZCBieSB0aGUgR05VIEdlbmVyYWwgUHVibGljCi8vIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgovLyBIb3dldmVyLCB0aGUgZm9sbG93aW5nIG5vdGljZSBhY2NvbXBhbmllZCB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGlzCi8vIGZpbGU6Ci8vCi8vCi8vICBMaXR0bGUgY21zCi8vICBDb3B5cmlnaHQgKEMpIDE5OTgtMjAwNiBNYXJ0aSBNYXJpYQovLwovLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKLy8gYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAovLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCi8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAovLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUKLy8gaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLy8KLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi8vCi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELAovLyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8KLy8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQKLy8gTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRQovLyBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OCi8vIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTgovLyBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KCgojaW5jbHVkZSAibGNtcy5oIgoKCi8vIFZpcnR1YWwgKGJ1aWx0LWluKSBwcm9maWxlcwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCi8vIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyBhIHByb2ZpbGUgYmFzZWQgb24gV2hpdGUgcG9pbnQsIHByaW1hcmllcyBhbmQKLy8gdHJhbnNmZXIgZnVuY3Rpb25zLgoKCmNtc0hQUk9GSUxFIExDTVNFWFBPUlQgY21zQ3JlYXRlUkdCUHJvZmlsZShMUGNtc0NJRXh5WSBXaGl0ZVBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQY21zQ0lFeHlZVFJJUExFIFByaW1hcmllcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEdBTU1BVEFCTEUgVHJhbnNmZXJGdW5jdGlvblszXSkKewogICAgICAgY21zSFBST0ZJTEUgaElDQzsKICAgICAgIGNtc0NJRVhZWiB0bXA7CiAgICAgICBNQVQzIE1Db2xvcmFudHM7CiAgICAgICBjbXNDSUVYWVpUUklQTEUgQ29sb3JhbnRzOwogICAgICAgY21zQ0lFeHlZIE1heFdoaXRlOwoKCiAgICAgICBoSUNDID0gX2Ntc0NyZWF0ZVByb2ZpbGVQbGFjZWhvbGRlcigpOwogICAgICAgaWYgKCFoSUNDKSAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuJ3QgYWxsb2NhdGUKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgoKICAgICAgIGNtc1NldERldmljZUNsYXNzKGhJQ0MsICAgICAgaWNTaWdEaXNwbGF5Q2xhc3MpOwogICAgICAgY21zU2V0Q29sb3JTcGFjZShoSUNDLCAgICAgICBpY1NpZ1JnYkRhdGEpOwogICAgICAgY21zU2V0UENTKGhJQ0MsICAgICAgICAgICAgICBpY1NpZ1hZWkRhdGEpOwogICAgICAgY21zU2V0UmVuZGVyaW5nSW50ZW50KGhJQ0MsICBJTlRFTlRfUEVSQ0VQVFVBTCk7CgoKICAgICAgIC8vIEltcGxlbWVudCBwcm9maWxlIHVzaW5nIGZvbGxvd2luZyB0YWdzOgogICAgICAgLy8KICAgICAgIC8vICAxIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnCiAgICAgICAvLyAgMiBpY1NpZ01lZGlhV2hpdGVQb2ludFRhZwogICAgICAgLy8gIDMgaWNTaWdSZWRDb2xvcmFudFRhZwogICAgICAgLy8gIDQgaWNTaWdHcmVlbkNvbG9yYW50VGFnCiAgICAgICAvLyAgNSBpY1NpZ0JsdWVDb2xvcmFudFRhZwogICAgICAgLy8gIDYgaWNTaWdSZWRUUkNUYWcKICAgICAgIC8vICA3IGljU2lnR3JlZW5UUkNUYWcKICAgICAgIC8vICA4IGljU2lnQmx1ZVRSQ1RhZwoKICAgICAgIC8vIFRoaXMgY29uZm9ybXMgYSBzdGFuZGFyZCBSR0IgRGlzcGxheVByb2ZpbGUgYXMgc2F5cyBJQ0MsIGFuZCB0aGVuIEkgYWRkCgogICAgICAgLy8gOSBpY1NpZ0Nocm9tYXRpY2l0eVRhZwoKICAgICAgIC8vIEFzIGFkZGVuZHVtIElJCgoKICAgICAgIC8vIEZpbGwtaW4gdGhlIHRhZ3MKCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNZmdEZXNjVGFnLCAgICAgICAoTFBWT0lEKSAiKGxjbXMgaW50ZXJuYWwpIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsICAoTFBWT0lEKSAibGNtcyBSR0IgdmlydHVhbCBwcm9maWxlIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgICAoTFBWT0lEKSAicmdiIGJ1aWx0LWluIik7CgoKICAgICAgIGlmIChXaGl0ZVBvaW50KSB7CgogICAgICAgY21zeHlZMlhZWigmdG1wLCBXaGl0ZVBvaW50KTsKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ01lZGlhV2hpdGVQb2ludFRhZywgKExQVk9JRCkgJnRtcCk7CiAgICAgICB9CgogICAgICAgaWYgKFdoaXRlUG9pbnQgJiYgUHJpbWFyaWVzKSB7CgogICAgICAgIE1heFdoaXRlLnggPSAgV2hpdGVQb2ludCAtPiB4OwogICAgICAgIE1heFdoaXRlLnkgPSAgV2hpdGVQb2ludCAtPiB5OwogICAgICAgIE1heFdoaXRlLlkgPSAgMS4wOwoKICAgICAgIGlmICghY21zQnVpbGRSR0IyWFladHJhbnNmZXJNYXRyaXgoJk1Db2xvcmFudHMsICZNYXhXaGl0ZSwgUHJpbWFyaWVzKSkKICAgICAgIHsKICAgICAgICAgICAgICBjbXNDbG9zZVByb2ZpbGUoaElDQyk7CiAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICB9CgogICAgICAgY21zQWRhcHRNYXRyaXhUb0Q1MCgmTUNvbG9yYW50cywgJk1heFdoaXRlKTsKCiAgICAgICBDb2xvcmFudHMuUmVkLlggPSBNQ29sb3JhbnRzLnZbMF0ublswXTsKICAgICAgIENvbG9yYW50cy5SZWQuWSA9IE1Db2xvcmFudHMudlsxXS5uWzBdOwogICAgICAgQ29sb3JhbnRzLlJlZC5aID0gTUNvbG9yYW50cy52WzJdLm5bMF07CgogICAgICAgQ29sb3JhbnRzLkdyZWVuLlggPSBNQ29sb3JhbnRzLnZbMF0ublsxXTsKICAgICAgIENvbG9yYW50cy5HcmVlbi5ZID0gTUNvbG9yYW50cy52WzFdLm5bMV07CiAgICAgICBDb2xvcmFudHMuR3JlZW4uWiA9IE1Db2xvcmFudHMudlsyXS5uWzFdOwoKICAgICAgIENvbG9yYW50cy5CbHVlLlggPSBNQ29sb3JhbnRzLnZbMF0ublsyXTsKICAgICAgIENvbG9yYW50cy5CbHVlLlkgPSBNQ29sb3JhbnRzLnZbMV0ublsyXTsKICAgICAgIENvbG9yYW50cy5CbHVlLlogPSBNQ29sb3JhbnRzLnZbMl0ublsyXTsKCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdSZWRDb2xvcmFudFRhZywgICAoTFBWT0lEKSAmQ29sb3JhbnRzLlJlZCk7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdCbHVlQ29sb3JhbnRUYWcsICAoTFBWT0lEKSAmQ29sb3JhbnRzLkJsdWUpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnR3JlZW5Db2xvcmFudFRhZywgKExQVk9JRCkgJkNvbG9yYW50cy5HcmVlbik7CiAgICAgICB9CgoKICAgICAgIGlmIChUcmFuc2ZlckZ1bmN0aW9uKSB7CgogICAgICAgLy8gSW4gY2FzZSBvZiBnYW1tYSwgd2UgbXVzdCBkdXAnIHRoZSB0YWJsZSBwb2ludGVyCgogICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ1JlZFRSQ1RhZywgICAoTFBWT0lEKSBUcmFuc2ZlckZ1bmN0aW9uWzBdKTsKICAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdHcmVlblRSQ1RhZywgKExQVk9JRCkgVHJhbnNmZXJGdW5jdGlvblsxXSk7CiAgICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnQmx1ZVRSQ1RhZywgIChMUFZPSUQpIFRyYW5zZmVyRnVuY3Rpb25bMl0pOwogICAgICAgfQoKICAgICAgIGlmIChQcmltYXJpZXMpIHsKICAgICAgICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnQ2hyb21hdGljaXR5VGFnLCAoTFBWT0lEKSBQcmltYXJpZXMpOwogICAgICAgfQoKICAgICAgIHJldHVybiBoSUNDOwp9CgoKCi8vIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyBhIHByb2ZpbGUgYmFzZWQgb24gV2hpdGUgcG9pbnQgYW5kIHRyYW5zZmVyIGZ1bmN0aW9uLgoKY21zSFBST0ZJTEUgICBMQ01TRVhQT1JUIGNtc0NyZWF0ZUdyYXlQcm9maWxlKExQY21zQ0lFeHlZIFdoaXRlUG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEdBTU1BVEFCTEUgVHJhbnNmZXJGdW5jdGlvbikKewogICAgICAgY21zSFBST0ZJTEUgaElDQzsKICAgICAgIGNtc0NJRVhZWiB0bXA7CgoKICAgICAgIGhJQ0MgPSBfY21zQ3JlYXRlUHJvZmlsZVBsYWNlaG9sZGVyKCk7CiAgICAgICBpZiAoIWhJQ0MpICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW4ndCBhbGxvY2F0ZQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCgogICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaElDQywgICAgICBpY1NpZ0Rpc3BsYXlDbGFzcyk7CiAgICAgICBjbXNTZXRDb2xvclNwYWNlKGhJQ0MsICAgICAgIGljU2lnR3JheURhdGEpOwogICAgICAgY21zU2V0UENTKGhJQ0MsICAgICAgICAgICAgICBpY1NpZ1hZWkRhdGEpOwogICAgICAgY21zU2V0UmVuZGVyaW5nSW50ZW50KGhJQ0MsICBJTlRFTlRfUEVSQ0VQVFVBTCk7CgoKCiAgICAgICAvLyBJbXBsZW1lbnQgcHJvZmlsZSB1c2luZyBmb2xsb3dpbmcgdGFnczoKICAgICAgIC8vCiAgICAgICAvLyAgMSBpY1NpZ1Byb2ZpbGVEZXNjcmlwdGlvblRhZwogICAgICAgLy8gIDIgaWNTaWdNZWRpYVdoaXRlUG9pbnRUYWcKICAgICAgIC8vICA2IGljU2lnR3JheVRSQ1RhZwoKICAgICAgIC8vIFRoaXMgY29uZm9ybXMgYSBzdGFuZGFyZCBHcmF5IERpc3BsYXlQcm9maWxlCgogICAgICAgLy8gRmlsbC1pbiB0aGUgdGFncwoKCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNZmdEZXNjVGFnLCAgICAgICAoTFBWT0lEKSAiKGxjbXMgaW50ZXJuYWwpIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsICAoTFBWT0lEKSAibGNtcyBncmF5IHZpcnR1YWwgcHJvZmlsZSIpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnRGV2aWNlTW9kZWxEZXNjVGFnLCAgICAgKExQVk9JRCkgImdyYXkgYnVpbHQtaW4iKTsKCgogICAgICAgaWYgKFdoaXRlUG9pbnQpIHsKCiAgICAgICBjbXN4eVkyWFlaKCZ0bXAsIFdoaXRlUG9pbnQpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnTWVkaWFXaGl0ZVBvaW50VGFnLCAoTFBWT0lEKSAmdG1wKTsKICAgICAgIH0KCgogICAgICAgaWYgKFRyYW5zZmVyRnVuY3Rpb24pIHsKCiAgICAgICAvLyBJbiBjYXNlIG9mIGdhbW1hLCB3ZSBtdXN0IGR1cCcgdGhlIHRhYmxlIHBvaW50ZXIKCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdHcmF5VFJDVGFnLCAoTFBWT0lEKSBUcmFuc2ZlckZ1bmN0aW9uKTsKICAgICAgIH0KCiAgICAgICByZXR1cm4gaElDQzsKCn0KCgpzdGF0aWMKaW50IElzUENTKGljQ29sb3JTcGFjZVNpZ25hdHVyZSBDb2xvclNwYWNlKQp7CiAgICByZXR1cm4gKENvbG9yU3BhY2UgPT0gaWNTaWdYWVpEYXRhIHx8CiAgICAgICAgICAgIENvbG9yU3BhY2UgPT0gaWNTaWdMYWJEYXRhKTsKfQoKc3RhdGljCnZvaWQgRml4Q29sb3JTcGFjZXMoY21zSFBST0ZJTEUgaFByb2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljQ29sb3JTcGFjZVNpZ25hdHVyZSBDb2xvclNwYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY0NvbG9yU3BhY2VTaWduYXR1cmUgUENTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0ZsYWdzKQp7CgogICAgaWYgKGR3RmxhZ3MgJiBjbXNGTEFHU19HVUVTU0RFVklDRUNMQVNTKSB7CgogICAgICAgICAgICBpZiAoSXNQQ1MoQ29sb3JTcGFjZSkgJiYgSXNQQ1MoUENTKSkgewoKICAgICAgICAgICAgICAgICAgICBjbXNTZXREZXZpY2VDbGFzcyhoUHJvZmlsZSwgICAgICBpY1NpZ0Fic3RyYWN0Q2xhc3MpOwogICAgICAgICAgICAgICAgICAgIGNtc1NldENvbG9yU3BhY2UoaFByb2ZpbGUsICAgICAgIENvbG9yU3BhY2UpOwogICAgICAgICAgICAgICAgICAgIGNtc1NldFBDUyhoUHJvZmlsZSwgICAgICAgICAgICAgIFBDUyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoSXNQQ1MoQ29sb3JTcGFjZSkgJiYgIUlzUENTKFBDUykpIHsKCiAgICAgICAgICAgICAgICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGUsIGljU2lnT3V0cHV0Q2xhc3MpOwogICAgICAgICAgICAgICAgICAgIGNtc1NldFBDUyhoUHJvZmlsZSwgICAgICAgICBDb2xvclNwYWNlKTsKICAgICAgICAgICAgICAgICAgICBjbXNTZXRDb2xvclNwYWNlKGhQcm9maWxlLCAgUENTKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChJc1BDUyhQQ1MpICYmICFJc1BDUyhDb2xvclNwYWNlKSkgewoKICAgICAgICAgICAgICAgICAgIGNtc1NldERldmljZUNsYXNzKGhQcm9maWxlLCAgaWNTaWdJbnB1dENsYXNzKTsKICAgICAgICAgICAgICAgICAgIGNtc1NldENvbG9yU3BhY2UoaFByb2ZpbGUsICAgQ29sb3JTcGFjZSk7CiAgICAgICAgICAgICAgICAgICBjbXNTZXRQQ1MoaFByb2ZpbGUsICAgICAgICAgIFBDUyk7CiAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgIH0KCiAgICBjbXNTZXREZXZpY2VDbGFzcyhoUHJvZmlsZSwgICAgICBpY1NpZ0xpbmtDbGFzcyk7CiAgICBjbXNTZXRDb2xvclNwYWNlKGhQcm9maWxlLCAgICAgICBDb2xvclNwYWNlKTsKICAgIGNtc1NldFBDUyhoUHJvZmlsZSwgICAgICAgICAgICAgIFBDUyk7Cgp9CgoKc3RhdGljCmNtc0hQUk9GSUxFIENyZWF0ZU5hbWVkQ29sb3JEZXZpY2VsaW5rKGNtc0hUUkFOU0ZPUk0geGZvcm0pCnsKICAgIF9MUGNtc1RSQU5TRk9STSB2ID0gKF9MUGNtc1RSQU5TRk9STSkgeGZvcm07CiAgICBjbXNIUFJPRklMRSBoSUNDOwogICAgY21zQ0lFWFlaIFdoaXRlUG9pbnQ7CiAgICBpbnQgaSwgbkNvbG9yczsKICAgIHNpemVfdCBTaXplOwogICAgTFBjbXNOQU1FRENPTE9STElTVCBuYzI7CgoKICAgIGhJQ0MgPSBfY21zQ3JlYXRlUHJvZmlsZVBsYWNlaG9sZGVyKCk7CiAgICBpZiAoaElDQyA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBjbXNTZXRSZW5kZXJpbmdJbnRlbnQoaElDQywgdiAtPiBJbnRlbnQpOwogICAgY21zU2V0RGV2aWNlQ2xhc3MoaElDQywgaWNTaWdOYW1lZENvbG9yQ2xhc3MpOwogICAgY21zU2V0Q29sb3JTcGFjZShoSUNDLCB2IC0+RXhpdENvbG9yU3BhY2UpOwogICAgY21zU2V0UENTKGhJQ0MsIGNtc0dldFBDUyh2IC0+SW5wdXRQcm9maWxlKSk7CiAgICBjbXNUYWtlTWVkaWFXaGl0ZVBvaW50KCZXaGl0ZVBvaW50LCB2IC0+SW5wdXRQcm9maWxlKTsKCiAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdNZWRpYVdoaXRlUG9pbnRUYWcsICAmV2hpdGVQb2ludCk7CiAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNZmdEZXNjVGFnLCAgICAgICAoTFBWT0lEKSAiTGl0dGxlQ01TIik7CiAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsICAoTFBWT0lEKSAiTmFtZWQgY29sb3IgRGV2aWNlIGxpbmsiKTsKICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0RldmljZU1vZGVsRGVzY1RhZywgICAgIChMUFZPSUQpICJOYW1lZCBjb2xvciBEZXZpY2UgbGluayIpOwoKCiAgICBuQ29sb3JzID0gY21zTmFtZWRDb2xvckNvdW50KHhmb3JtKTsKICAgIG5jMiAgICAgPSBjbXNBbGxvY05hbWVkQ29sb3JMaXN0KG5Db2xvcnMpOwoKICAgIFNpemUgPSBzaXplb2YoY21zTkFNRURDT0xPUkxJU1QpICsgKHNpemVvZihjbXNOQU1FRENPTE9SKSAqIChuQ29sb3JzLTEpKTsKCiAgICBDb3B5TWVtb3J5KG5jMiwgdi0+TmFtZWRDb2xvckxpc3QsIFNpemUpOwogICAgbmMyIC0+Q29sb3JhbnRDb3VudCA9IF9jbXNDaGFubmVsc09mKHYgLT5FeGl0Q29sb3JTcGFjZSk7CgogICAgZm9yIChpPTA7IGkgPCBuQ29sb3JzOyBpKyspIHsKICAgICAgICBjbXNEb1RyYW5zZm9ybSh4Zm9ybSwgJmksIG5jMiAtPkxpc3RbaV0uRGV2aWNlQ29sb3JhbnQsIDEpOwogICAgfQoKICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ05hbWVkQ29sb3IyVGFnLCAodm9pZCopIG5jMik7CiAgICBjbXNGcmVlTmFtZWRDb2xvckxpc3QobmMyKTsKCiAgICByZXR1cm4gaElDQzsKfQoKCi8vIERvZXMgY29udmVydCBhIHRyYW5zZm9ybSBpbnRvIGEgZGV2aWNlIGxpbmsgcHJvZmlsZQoKY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNUcmFuc2Zvcm0yRGV2aWNlTGluayhjbXNIVFJBTlNGT1JNIGhUcmFuc2Zvcm0sIERXT1JEIGR3RmxhZ3MpCnsKICAgIGNtc0hQUk9GSUxFIGhJQ0M7CiAgICBfTFBjbXNUUkFOU0ZPUk0gdiA9IChfTFBjbXNUUkFOU0ZPUk0pIGhUcmFuc2Zvcm07CiAgICBMUExVVCBMdXQ7CiAgICBCT09MIE11c3RGcmVlTFVUOwogICAgTFBjbXNOQU1FRENPTE9STElTVCBJbnB1dENvbG9yYW50ID0gTlVMTDsKICAgIExQY21zTkFNRURDT0xPUkxJU1QgT3V0cHV0Q29sb3JhbnQgPSBOVUxMOwoKCiAgICAvLyBDaGVjayBpZiBpcyBhIG5hbWVkIGNvbG9yIHRyYW5zZm9ybQoKICAgIGlmIChjbXNHZXREZXZpY2VDbGFzcyh2IC0+SW5wdXRQcm9maWxlKSA9PSBpY1NpZ05hbWVkQ29sb3JDbGFzcykgewoKICAgICAgICByZXR1cm4gQ3JlYXRlTmFtZWRDb2xvckRldmljZWxpbmsoaFRyYW5zZm9ybSk7CgogICAgfQoKICAgIGlmICh2IC0+RGV2aWNlTGluaykgewoKICAgICAgICBMdXQgPSB2IC0+IERldmljZUxpbms7CiAgICAgICAgTXVzdEZyZWVMVVQgPSBGQUxTRTsKICAgIH0KICAgIGVsc2UgewoKICAgICAgICBMdXQgPSBfY21zUHJlY2FsY3VsYXRlRGV2aWNlTGluayhoVHJhbnNmb3JtLCBkd0ZsYWdzKTsKICAgICAgICBpZiAoIUx1dCkgcmV0dXJuIE5VTEw7CiAgICAgICAgTXVzdEZyZWVMVVQgPSBUUlVFOwogICAgfQoKICAgIGhJQ0MgPSBfY21zQ3JlYXRlUHJvZmlsZVBsYWNlaG9sZGVyKCk7CiAgICBpZiAoIWhJQ0MpIHsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbid0IGFsbG9jYXRlCgogICAgICAgIGlmIChNdXN0RnJlZUxVVCkgY21zRnJlZUxVVChMdXQpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKCiAgICBGaXhDb2xvclNwYWNlcyhoSUNDLCB2IC0+IEVudHJ5Q29sb3JTcGFjZSwgdiAtPiBFeGl0Q29sb3JTcGFjZSwgZHdGbGFncyk7CgogICAgY21zU2V0UmVuZGVyaW5nSW50ZW50KGhJQ0MsICB2IC0+IEludGVudCk7CgogICAgLy8gSW1wbGVtZW50IGRldmljZWxpbmsgcHJvZmlsZSB1c2luZyBmb2xsb3dpbmcgdGFnczoKICAgIC8vCiAgICAvLyAgMSBpY1NpZ1Byb2ZpbGVEZXNjcmlwdGlvblRhZwogICAgLy8gIDIgaWNTaWdNZWRpYVdoaXRlUG9pbnRUYWcKICAgIC8vICAzIGljU2lnQVRvQjBUYWcKCgogICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnRGV2aWNlTWZnRGVzY1RhZywgICAgICAgKExQVk9JRCkgIkxpdHRsZUNNUyIpOwogICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnLCAgKExQVk9JRCkgIkRldmljZSBsaW5rIik7CiAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgICAoTFBWT0lEKSAiRGV2aWNlIGxpbmsiKTsKCgogICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnTWVkaWFXaGl0ZVBvaW50VGFnLCAgKExQVk9JRCkgY21zRDUwX1hZWigpKTsKCiAgICBpZiAoY21zR2V0RGV2aWNlQ2xhc3MoaElDQykgPT0gaWNTaWdPdXRwdXRDbGFzcykgewoKCiAgICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnQlRvQTBUYWcsIChMUFZPSUQpIEx1dCk7CiAgICB9CgogICAgZWxzZQogICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0FUb0IwVGFnLCAoTFBWT0lEKSBMdXQpOwoKCgogICAgLy8gVHJ5IHRvIHJlYWQgaW5wdXQgYW5kIG91dHB1dCBjb2xvcmFudCB0YWJsZQogICAgaWYgKGNtc0lzVGFnKHYgLT5JbnB1dFByb2ZpbGUsIGljU2lnQ29sb3JhbnRUYWJsZVRhZykpIHsKCiAgICAgICAgLy8gSW5wdXQgdGFibGUgY2FuIG9ubHkgY29tZSBpbiB0aGlzIHdheS4KICAgICAgICBJbnB1dENvbG9yYW50ID0gY21zUmVhZENvbG9yYW50VGFibGUodiAtPklucHV0UHJvZmlsZSwgaWNTaWdDb2xvcmFudFRhYmxlVGFnKTsKICAgIH0KCiAgICAvLyBPdXRwdXQgaXMgYSBsaXR0bGUgYml0IG1vcmUgY29tcGxleC4KICAgIGlmIChjbXNHZXREZXZpY2VDbGFzcyh2IC0+T3V0cHV0UHJvZmlsZSkgPT0gaWNTaWdMaW5rQ2xhc3MpIHsKCiAgICAgICAgLy8gVGhpcyB0YWcgbWF5IGV4aXN0IG9ubHkgb24gZGV2aWNlbGluayBwcm9maWxlcy4KICAgICAgICBpZiAoY21zSXNUYWcodiAtPk91dHB1dFByb2ZpbGUsIGljU2lnQ29sb3JhbnRUYWJsZU91dFRhZykpIHsKCiAgICAgICAgICAgIE91dHB1dENvbG9yYW50ID0gY21zUmVhZENvbG9yYW50VGFibGUodiAtPk91dHB1dFByb2ZpbGUsIGljU2lnQ29sb3JhbnRUYWJsZU91dFRhZyk7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7CgogICAgICAgIGlmIChjbXNJc1RhZyh2IC0+T3V0cHV0UHJvZmlsZSwgaWNTaWdDb2xvcmFudFRhYmxlVGFnKSkgewoKICAgICAgICAgICAgT3V0cHV0Q29sb3JhbnQgPSBjbXNSZWFkQ29sb3JhbnRUYWJsZSh2IC0+T3V0cHV0UHJvZmlsZSwgaWNTaWdDb2xvcmFudFRhYmxlVGFnKTsKICAgICAgICB9CiAgICAgICAgfQoKICAgIGlmIChJbnB1dENvbG9yYW50KQogICAgICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0NvbG9yYW50VGFibGVUYWcsIElucHV0Q29sb3JhbnQpOwoKICAgIGlmIChPdXRwdXRDb2xvcmFudCkKICAgICAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdDb2xvcmFudFRhYmxlT3V0VGFnLCBPdXRwdXRDb2xvcmFudCk7CgoKCiAgICBpZiAoTXVzdEZyZWVMVVQpIGNtc0ZyZWVMVVQoTHV0KTsKICAgIGlmIChJbnB1dENvbG9yYW50KSBjbXNGcmVlTmFtZWRDb2xvckxpc3QoSW5wdXRDb2xvcmFudCk7CiAgICBpZiAoT3V0cHV0Q29sb3JhbnQpIGNtc0ZyZWVOYW1lZENvbG9yTGlzdChPdXRwdXRDb2xvcmFudCk7CgogICAgcmV0dXJuIGhJQ0M7Cgp9CgoKLy8gVGhpcyBpcyBhIGRldmljZWxpbmsgb3BlcmF0aW5nIGluIHRoZSB0YXJnZXQgY29sb3JzcGFjZSB3aXRoIGFzIG1hbnkgdHJhbnNmZXIKLy8gZnVuY3Rpb25zIGFzIGNvbXBvbmVudHMKCmNtc0hQUk9GSUxFIExDTVNFWFBPUlQgY21zQ3JlYXRlTGluZWFyaXphdGlvbkRldmljZUxpbmsoaWNDb2xvclNwYWNlU2lnbmF0dXJlIENvbG9yU3BhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBHQU1NQVRBQkxFIFRyYW5zZmVyRnVuY3Rpb25zW10pCnsKICAgICAgIGNtc0hQUk9GSUxFIGhJQ0M7CiAgICAgICBMUExVVCBMdXQ7CgoKICAgICAgIGhJQ0MgPSBfY21zQ3JlYXRlUHJvZmlsZVBsYWNlaG9sZGVyKCk7CiAgICAgICBpZiAoIWhJQ0MpICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW4ndCBhbGxvY2F0ZQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCgogICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaElDQywgICAgICBpY1NpZ0xpbmtDbGFzcyk7CiAgICAgICBjbXNTZXRDb2xvclNwYWNlKGhJQ0MsICAgICAgIENvbG9yU3BhY2UpOwogICAgICAgY21zU2V0UENTKGhJQ0MsICAgICAgICAgICAgICBDb2xvclNwYWNlKTsKICAgICAgIGNtc1NldFJlbmRlcmluZ0ludGVudChoSUNDLCAgSU5URU5UX1BFUkNFUFRVQUwpOwoKCiAgICAgICAvLyBDcmVhdGVzIGEgTFVUIHdpdGggcHJlbGluZWFyaXphdGlvbiBzdGVwIG9ubHkKICAgICAgIEx1dCA9IGNtc0FsbG9jTFVUKCk7CgogICAgICAgLy8gU2V0IHVwIGNoYW5uZWxzCiAgICAgICBMdXQgLT5JbnB1dENoYW4gPSBMdXQgLT5PdXRwdXRDaGFuID0gX2Ntc0NoYW5uZWxzT2YoQ29sb3JTcGFjZSk7CgogICAgICAgLy8gQ29weSB0YWJsZXMgdG8gTFVUCiAgICAgICBjbXNBbGxvY0xpbmVhclRhYmxlKEx1dCwgVHJhbnNmZXJGdW5jdGlvbnMsIDEpOwoKICAgICAgIC8vIENyZWF0ZSB0YWdzCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNZmdEZXNjVGFnLCAgICAgICAoTFBWT0lEKSAiKGxjbXMgaW50ZXJuYWwpIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsICAoTFBWT0lEKSAibGNtcyBsaW5lYXJpemF0aW9uIGRldmljZSBsaW5rIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgICAoTFBWT0lEKSAibGluZWFyaXphdGlvbiBidWlsdC1pbiIpOwoKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ01lZGlhV2hpdGVQb2ludFRhZywgKExQVk9JRCkgY21zRDUwX1hZWigpKTsKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0FUb0IwVGFnLCAoTFBWT0lEKSBMdXQpOwoKICAgICAgIC8vIExVVCBpcyBhbHJlYWR5IG9uIHZpcnR1YWwgcHJvZmlsZQogICAgICAgY21zRnJlZUxVVChMdXQpOwoKICAgICAgIC8vIE9rLCBkb25lCiAgICAgICByZXR1cm4gaElDQzsKfQoKCi8vIEluay1saW1pdGluZyBhbGdvcml0aG0KLy8KLy8gIFN1bSA9IEMgKyBNICsgWSArIEsKLy8gIElmIFN1bSA+IElua0xpbWl0Ci8vICAgICAgICBSYXRpbz0gMSAtIChTdW0gLSBJbmtMaW1pdCkgLyAoQyArIE0gKyBZKQovLyAgICAgICAgaWYgUmF0aW8gPDAKLy8gICAgICAgICAgICAgIFJhdGlvPTAKLy8gICAgICAgIGVuZGlmCi8vICAgICBFbHNlCi8vICAgICAgICAgUmF0aW89MQovLyAgICAgZW5kaWYKLy8KLy8gICAgIEMgPSBSYXRpbyAqIEMKLy8gICAgIE0gPSBSYXRpbyAqIE0KLy8gICAgIFkgPSBSYXRpbyAqIFkKLy8gICAgIEs6IERvZXMgbm90IGNoYW5nZQoKc3RhdGljCmludCBJbmtMaW1pdGluZ1NhbXBsZXIocmVnaXN0ZXIgV09SRCBJbltdLCByZWdpc3RlciBXT1JEIE91dFtdLCByZWdpc3RlciBMUFZPSUQgQ2FyZ28pCnsKICAgICAgICBkb3VibGUgSW5rTGltaXQgPSAqKGRvdWJsZSAqKSBDYXJnbzsKICAgICAgICBkb3VibGUgU3VtQ01ZLCBTdW1DTVlLLCBSYXRpbzsKCiAgICAgICAgSW5rTGltaXQgPSAoSW5rTGltaXQgKiA2NTUuMzUpOwoKICAgICAgICBTdW1DTVkgICA9IEluWzBdICArIEluWzFdICsgSW5bMl07CiAgICAgICAgU3VtQ01ZSyAgPSBTdW1DTVkgKyBJblszXTsKCiAgICAgICAgaWYgKFN1bUNNWUsgPiBJbmtMaW1pdCkgewoKICAgICAgICAgICAgICAgIFJhdGlvID0gMSAtICgoU3VtQ01ZSyAtIElua0xpbWl0KSAvIFN1bUNNWSk7CiAgICAgICAgICAgICAgICBpZiAoUmF0aW8gPCAwKQogICAgICAgICAgICAgICAgICAgICAgICBSYXRpbyA9IDA7CiAgICAgICAgfQogICAgICAgIGVsc2UgUmF0aW8gPSAxOwoKICAgICAgICBPdXRbMF0gPSAoV09SRCkgZmxvb3IoSW5bMF0gKiBSYXRpbyArIDAuNSk7ICAgICAvLyBDCiAgICAgICAgT3V0WzFdID0gKFdPUkQpIGZsb29yKEluWzFdICogUmF0aW8gKyAwLjUpOyAgICAgLy8gTQogICAgICAgIE91dFsyXSA9IChXT1JEKSBmbG9vcihJblsyXSAqIFJhdGlvICsgMC41KTsgICAgIC8vIFkKCiAgICAgICAgT3V0WzNdID0gSW5bM107ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSyAodW50b3VjaGVkKQoKICAgICAgICByZXR1cm4gVFJVRTsKfQoKLy8gVGhpcyBpcyBhIGRldmljZWxpbmsgb3BlcmF0aW5nIGluIENNWUsgZm9yIGluay1saW1pdGluZwoKY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVJbmtMaW1pdGluZ0RldmljZUxpbmsoaWNDb2xvclNwYWNlU2lnbmF0dXJlIENvbG9yU3BhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIExpbWl0KQp7CiAgICAgICBjbXNIUFJPRklMRSBoSUNDOwogICAgICAgTFBMVVQgTHV0OwoKICAgICAgIGlmIChDb2xvclNwYWNlICE9IGljU2lnQ215a0RhdGEpIHsKICAgICAgICAgICAgY21zU2lnbmFsRXJyb3IoTENNU19FUlJDX0FCT1JURUQsICJJbmtMaW1pdGluZzogT25seSBDTVlLIGN1cnJlbnRseSBzdXBwb3J0ZWQiKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICB9CgogICAgICAgaWYgKExpbWl0IDwgMC4wIHx8IExpbWl0ID4gNDAwKSB7CgogICAgICAgICAgIGNtc1NpZ25hbEVycm9yKExDTVNfRVJSQ19XQVJOSU5HLCAiSW5rTGltaXRpbmc6IExpbWl0IHNob3VsZCBiZSBiZXR3ZWVuIDAuLjQwMCIpOwogICAgICAgICAgIGlmIChMaW1pdCA8IDApIExpbWl0ID0gMDsKICAgICAgICAgICBpZiAoTGltaXQgPiA0MDApIExpbWl0ID0gNDAwOwoKICAgICAgIH0KCiAgICAgIGhJQ0MgPSBfY21zQ3JlYXRlUHJvZmlsZVBsYWNlaG9sZGVyKCk7CiAgICAgICBpZiAoIWhJQ0MpICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW4ndCBhbGxvY2F0ZQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCgogICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaElDQywgICAgICBpY1NpZ0xpbmtDbGFzcyk7CiAgICAgICBjbXNTZXRDb2xvclNwYWNlKGhJQ0MsICAgICAgIENvbG9yU3BhY2UpOwogICAgICAgY21zU2V0UENTKGhJQ0MsICAgICAgICAgICAgICBDb2xvclNwYWNlKTsKICAgICAgIGNtc1NldFJlbmRlcmluZ0ludGVudChoSUNDLCAgSU5URU5UX1BFUkNFUFRVQUwpOwoKCiAgICAgICAvLyBDcmVhdGVzIGEgTFVUIHdpdGggM0QgZ3JpZCBvbmx5CiAgICAgICBMdXQgPSBjbXNBbGxvY0xVVCgpOwoKCiAgICAgICBjbXNBbGxvYzNER3JpZChMdXQsIDE3LCBfY21zQ2hhbm5lbHNPZihDb2xvclNwYWNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jbXNDaGFubmVsc09mKENvbG9yU3BhY2UpKTsKCiAgICAgICBpZiAoIWNtc1NhbXBsZTNER3JpZChMdXQsIElua0xpbWl0aW5nU2FtcGxlciwgKExQVk9JRCkgJkxpbWl0LCAwKSkgewoKICAgICAgICAgICAgICAgIC8vIFNob3VsZG4ndCByZWFjaCBoZXJlCiAgICAgICAgICAgICAgICBjbXNGcmVlTFVUKEx1dCk7CiAgICAgICAgICAgICAgICBjbXNDbG9zZVByb2ZpbGUoaElDQyk7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgIH0KCiAgICAgICAvLyBDcmVhdGUgdGFncwoKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0RldmljZU1mZ0Rlc2NUYWcsICAgICAgKExQVk9JRCkgIihsY21zIGludGVybmFsKSIpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnLCAoTFBWT0lEKSAibGNtcyBpbmsgbGltaXRpbmcgZGV2aWNlIGxpbmsiKTsKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0RldmljZU1vZGVsRGVzY1RhZywgICAgKExQVk9JRCkgImluayBsaW1pdGluZyBidWlsdC1pbiIpOwoKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ01lZGlhV2hpdGVQb2ludFRhZywgKExQVk9JRCkgY21zRDUwX1hZWigpKTsKCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdBVG9CMFRhZywgKExQVk9JRCkgTHV0KTsKCiAgICAgICAvLyBMVVQgaXMgYWxyZWFkeSBvbiB2aXJ0dWFsIHByb2ZpbGUKICAgICAgIGNtc0ZyZWVMVVQoTHV0KTsKCiAgICAgICAvLyBPaywgZG9uZQogICAgICAgcmV0dXJuIGhJQ0M7Cn0KCgoKc3RhdGljCkxQTFVUIENyZWF0ZTN4M0VtcHR5TFVUKHZvaWQpCnsKICAgICAgICBMUExVVCBBVG9CMCA9IGNtc0FsbG9jTFVUKCk7CiAgICAgICAgQVRvQjAgLT4gSW5wdXRDaGFuID0gQVRvQjAgLT4gT3V0cHV0Q2hhbiA9IDM7CgogICAgICAgIHJldHVybiBBVG9CMDsKfQoKCgovLyBDcmVhdGVzIGEgZmFrZSBMYWIgaWRlbnRpdHkuCmNtc0hQUk9GSUxFIExDTVNFWFBPUlQgY21zQ3JlYXRlTGFiUHJvZmlsZShMUGNtc0NJRXh5WSBXaGl0ZVBvaW50KQp7CiAgICAgICAgY21zSFBST0ZJTEUgaFByb2ZpbGU7CiAgICAgICAgTFBMVVQgTHV0OwoKCiAgICAgICAgaFByb2ZpbGUgPSBjbXNDcmVhdGVSR0JQcm9maWxlKFdoaXRlUG9pbnQgPT0gTlVMTCA/IGNtc0Q1MF94eVkoKSA6IFdoaXRlUG9pbnQsIE5VTEwsIE5VTEwpOwoKICAgICAgICBjbXNTZXREZXZpY2VDbGFzcyhoUHJvZmlsZSwgaWNTaWdBYnN0cmFjdENsYXNzKTsKICAgICAgICBjbXNTZXRDb2xvclNwYWNlKGhQcm9maWxlLCAgaWNTaWdMYWJEYXRhKTsKICAgICAgICBjbXNTZXRQQ1MoaFByb2ZpbGUsICAgICAgICAgaWNTaWdMYWJEYXRhKTsKCiAgICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ0RldmljZU1mZ0Rlc2NUYWcsICAgICAoTFBWT0lEKSAiKGxjbXMgaW50ZXJuYWwpIik7CiAgICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ1Byb2ZpbGVEZXNjcmlwdGlvblRhZywgKExQVk9JRCkgImxjbXMgTGFiIGlkZW50aXR5Iik7CiAgICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ0RldmljZU1vZGVsRGVzY1RhZywgICAgKExQVk9JRCkgIkxhYiBidWlsdC1pbiIpOwoKCiAgICAgICAvLyBBbiBlbXB0eSBMVVRzIGlzIGFsbCB3ZSBuZWVkCiAgICAgICBMdXQgPSBDcmVhdGUzeDNFbXB0eUxVVCgpOwogICAgICAgaWYgKEx1dCA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnQVRvQjBUYWcsICAgIChMUFZPSUQpIEx1dCk7CiAgICAgICBjbXNBZGRUYWcoaFByb2ZpbGUsIGljU2lnQlRvQTBUYWcsICAgIChMUFZPSUQpIEx1dCk7CgogICAgICAgY21zRnJlZUxVVChMdXQpOwoKICAgICAgIHJldHVybiBoUHJvZmlsZTsKfQoKCi8vIENyZWF0ZXMgYSBmYWtlIExhYiBpZGVudGl0eS4KY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVMYWI0UHJvZmlsZShMUGNtc0NJRXh5WSBXaGl0ZVBvaW50KQp7CiAgICAgICAgY21zSFBST0ZJTEUgaFByb2ZpbGU7CiAgICAgICAgTFBMVVQgTHV0OwoKCiAgICAgICAgaFByb2ZpbGUgPSBjbXNDcmVhdGVSR0JQcm9maWxlKFdoaXRlUG9pbnQgPT0gTlVMTCA/IGNtc0Q1MF94eVkoKSA6IFdoaXRlUG9pbnQsIE5VTEwsIE5VTEwpOwoKICAgICAgICBjbXNTZXRQcm9maWxlSUNDdmVyc2lvbihoUHJvZmlsZSwgMHg0MDAwMDAwKTsKCiAgICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGUsIGljU2lnQWJzdHJhY3RDbGFzcyk7CiAgICAgICAgY21zU2V0Q29sb3JTcGFjZShoUHJvZmlsZSwgIGljU2lnTGFiRGF0YSk7CiAgICAgICAgY21zU2V0UENTKGhQcm9maWxlLCAgICAgICAgIGljU2lnTGFiRGF0YSk7CgogICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdEZXZpY2VNZmdEZXNjVGFnLCAgICAgKExQVk9JRCkgIihsY21zIGludGVybmFsKSIpOwogICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsIChMUFZPSUQpICJsY21zIExhYiBpZGVudGl0eSB2NCIpOwogICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgIChMUFZPSUQpICJMYWIgdjQgYnVpbHQtaW4iKTsKCgogICAgICAgLy8gQW4gZW1wdHkgTFVUcyBpcyBhbGwgd2UgbmVlZAogICAgICAgTHV0ID0gQ3JlYXRlM3gzRW1wdHlMVVQoKTsKICAgICAgIGlmIChMdXQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgICAgTHV0IC0+IHdGbGFncyB8PSBMVVRfVjRfSU5QVVRfRU1VTEFURV9WMjsKICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdBVG9CMFRhZywgICAgKExQVk9JRCkgTHV0KTsKCiAgICAgICBMdXQgLT4gd0ZsYWdzIHw9IExVVF9WNF9PVVRQVVRfRU1VTEFURV9WMjsKICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdCVG9BMFRhZywgICAgKExQVk9JRCkgTHV0KTsKCiAgICAgICBjbXNGcmVlTFVUKEx1dCk7CgogICAgICAgcmV0dXJuIGhQcm9maWxlOwp9CgoKCi8vIENyZWF0ZXMgYSBmYWtlIFhZWiBpZGVudGl0eQpjbXNIUFJPRklMRSBMQ01TRVhQT1JUIGNtc0NyZWF0ZVhZWlByb2ZpbGUodm9pZCkKewogICAgICAgIGNtc0hQUk9GSUxFIGhQcm9maWxlOwogICAgICAgIExQTFVUIEx1dDsKCiAgICAgICAgaFByb2ZpbGUgPSBjbXNDcmVhdGVSR0JQcm9maWxlKGNtc0Q1MF94eVkoKSwgTlVMTCwgTlVMTCk7CgogICAgICAgIGNtc1NldERldmljZUNsYXNzKGhQcm9maWxlLCBpY1NpZ0Fic3RyYWN0Q2xhc3MpOwogICAgICAgIGNtc1NldENvbG9yU3BhY2UoaFByb2ZpbGUsIGljU2lnWFlaRGF0YSk7CiAgICAgICAgY21zU2V0UENTKGhQcm9maWxlLCAgaWNTaWdYWVpEYXRhKTsKCiAgICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ0RldmljZU1mZ0Rlc2NUYWcsICAgICAgKExQVk9JRCkgIihsY21zIGludGVybmFsKSIpOwogICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsIChMUFZPSUQpICJsY21zIFhZWiBpZGVudGl0eSIpOwogICAgICAgIGNtc0FkZFRhZyhoUHJvZmlsZSwgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgIChMUFZPSUQpICAiWFlaIGJ1aWx0LWluIik7CgogICAgICAgLy8gQW4gZW1wdHkgTFVUcyBpcyBhbGwgd2UgbmVlZAogICAgICAgTHV0ID0gQ3JlYXRlM3gzRW1wdHlMVVQoKTsKICAgICAgIGlmIChMdXQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ0FUb0IwVGFnLCAgICAoTFBWT0lEKSBMdXQpOwogICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ0JUb0EwVGFnLCAgICAoTFBWT0lEKSBMdXQpOwogICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ1ByZXZpZXcwVGFnLCAoTFBWT0lEKSBMdXQpOwoKICAgICAgIGNtc0ZyZWVMVVQoTHV0KTsKCgogICAgICAgcmV0dXJuIGhQcm9maWxlOwp9CgoKCi8qCgpJZiAgUpJzUkdCLEeSc1JHQiwgQpJzUkdCIDwgMC4wNDA0NQoKICAgIFIgPSAgUpJzUkdCIC8gMTIuOTIKICAgIEcgPSAgR5JzUkdCIC8gMTIuOTIKICAgIEIgPSAgQpJzUkdCIC8gMTIuOTIKCgoKZWxzZSBpZiAgUpJzUkdCLEeSc1JHQiwgQpJzUkdCID49IDAuMDQwNDUKCiAgICBSID0gKChSknNSR0IgKyAwLjA1NSkgLyAxLjA1NSleMi40CiAgICBHID0gKChHknNSR0IgKyAwLjA1NSkgLyAxLjA1NSleMi40CiAgICBCID0gKChCknNSR0IgKyAwLjA1NSkgLyAxLjA1NSleMi40CgogICovCgpzdGF0aWMKTFBHQU1NQVRBQkxFIEJ1aWxkX3NSR0JHYW1tYSh2b2lkKQp7CiAgICBkb3VibGUgUGFyYW1ldGVyc1s1XTsKCiAgICBQYXJhbWV0ZXJzWzBdID0gMi40OwogICAgUGFyYW1ldGVyc1sxXSA9IDEuIC8gMS4wNTU7CiAgICBQYXJhbWV0ZXJzWzJdID0gMC4wNTUgLyAxLjA1NTsKICAgIFBhcmFtZXRlcnNbM10gPSAxLiAvIDEyLjkyOwogICAgUGFyYW1ldGVyc1s0XSA9IDAuMDQwNDU7ICAgIC8vIGQKCiAgICByZXR1cm4gY21zQnVpbGRQYXJhbWV0cmljR2FtbWEoMTAyNCwgNCwgUGFyYW1ldGVycyk7Cn0KCmNtc0hQUk9GSUxFIExDTVNFWFBPUlQgY21zQ3JlYXRlX3NSR0JQcm9maWxlKHZvaWQpCnsKICAgICAgIGNtc0NJRXh5WSAgICAgICBENjU7CiAgICAgICBjbXNDSUV4eVlUUklQTEUgUmVjNzA5UHJpbWFyaWVzID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHswLjY0MDAsIDAuMzMwMCwgMS4wfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7MC4zMDAwLCAwLjYwMDAsIDEuMH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgezAuMTUwMCwgMC4wNjAwLCAxLjB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgIExQR0FNTUFUQUJMRSBHYW1tYTIyWzNdOwogICAgICAgY21zSFBST0ZJTEUgIGhzUkdCOwoKICAgICAgIGNtc1doaXRlUG9pbnRGcm9tVGVtcCg2NTA0LCAmRDY1KTsKICAgICAgIEdhbW1hMjJbMF0gPSBHYW1tYTIyWzFdID0gR2FtbWEyMlsyXSA9IEJ1aWxkX3NSR0JHYW1tYSgpOwoKICAgICAgIGhzUkdCID0gY21zQ3JlYXRlUkdCUHJvZmlsZSgmRDY1LCAmUmVjNzA5UHJpbWFyaWVzLCBHYW1tYTIyKTsKICAgICAgIGNtc0ZyZWVHYW1tYShHYW1tYTIyWzBdKTsKCgogICAgICAgY21zQWRkVGFnKGhzUkdCLCBpY1NpZ0RldmljZU1mZ0Rlc2NUYWcsICAgICAgKExQVk9JRCkgIihsY21zIGludGVybmFsKSIpOwogICAgICAgY21zQWRkVGFnKGhzUkdCLCBpY1NpZ0RldmljZU1vZGVsRGVzY1RhZywgICAgKExQVk9JRCkgInNSR0IgYnVpbHQtaW4iKTsKICAgICAgIGNtc0FkZFRhZyhoc1JHQiwgaWNTaWdQcm9maWxlRGVzY3JpcHRpb25UYWcsIChMUFZPSUQpICJzUkdCIGJ1aWx0LWluIik7CgogICAgICAgcmV0dXJuIGhzUkdCOwp9CgoKCgp0eXBlZGVmIHN0cnVjdCB7CiAgICAgICAgICAgICAgICBkb3VibGUgQnJpZ2h0bmVzczsKICAgICAgICAgICAgICAgIGRvdWJsZSBDb250cmFzdDsKICAgICAgICAgICAgICAgIGRvdWJsZSBIdWU7CiAgICAgICAgICAgICAgICBkb3VibGUgU2F0dXJhdGlvbjsKICAgICAgICAgICAgICAgIGNtc0NJRVhZWiBXUHNyYywgV1BkZXN0OwoKfSBCQ0hTV0FESlVTVFMsICpMUEJDSFNXQURKVVNUUzsKCgpzdGF0aWMKaW50IGJjaHN3U2FtcGxlcihyZWdpc3RlciBXT1JEIEluW10sIHJlZ2lzdGVyIFdPUkQgT3V0W10sIHJlZ2lzdGVyIExQVk9JRCBDYXJnbykKewogICAgY21zQ0lFTGFiIExhYkluLCBMYWJPdXQ7CiAgICBjbXNDSUVMQ2ggTENoSW4sIExDaE91dDsKICAgIGNtc0NJRVhZWiBYWVo7CiAgICBMUEJDSFNXQURKVVNUUyBiY2hzdyA9IChMUEJDSFNXQURKVVNUUykgQ2FyZ287CgoKICAgIGNtc0xhYkVuY29kZWQyRmxvYXQoJkxhYkluLCBJbik7CgoKICAgIGNtc0xhYjJMQ2goJkxDaEluLCAmTGFiSW4pOwoKICAgIC8vIERvIHNvbWUgYWRqdXN0cyBvbiBMQ2gKCiAgICBMQ2hPdXQuTCA9IExDaEluLkwgKiBiY2hzdyAtPkNvbnRyYXN0ICsgYmNoc3cgLT5CcmlnaHRuZXNzOwogICAgTENoT3V0LkMgPSBMQ2hJbi5DICsgYmNoc3cgLT4gU2F0dXJhdGlvbjsKICAgIExDaE91dC5oID0gTENoSW4uaCArIGJjaHN3IC0+IEh1ZTsKCgogICAgY21zTENoMkxhYigmTGFiT3V0LCAmTENoT3V0KTsKCiAgICAvLyBNb3ZlIHdoaXRlIHBvaW50IGluIExhYgoKICAgIGNtc0xhYjJYWVooJmJjaHN3IC0+V1BzcmMsICAmWFlaLCAmTGFiT3V0KTsKICAgIGNtc1hZWjJMYWIoJmJjaHN3IC0+V1BkZXN0LCAmTGFiT3V0LCAmWFlaKTsKCiAgICAvLyBCYWNrIHRvIGVuY29kZWQKCiAgICBjbXNGbG9hdDJMYWJFbmNvZGVkKE91dCwgJkxhYk91dCk7CgoKICAgIHJldHVybiBUUlVFOwp9CgoKLy8gQ3JlYXRlcyBhbiBhYnN0cmFjdCBwcm9maWxlIG9wZXJhdGluZyBpbiBMYWIgc3BhY2UgZm9yIEJyaWdodG5lc3MsCi8vIGNvbnRyYXN0LCBTYXR1cmF0aW9uIGFuZCB3aGl0ZSBwb2ludCBkaXNwbGFjZW1lbnQKCmNtc0hQUk9GSUxFIExDTVNFWFBPUlQgY21zQ3JlYXRlQkNIU1dhYnN0cmFjdFByb2ZpbGUoaW50IG5MVVRQb2ludHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIEJyaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgQ29udHJhc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIEh1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3VibGUgU2F0dXJhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgVGVtcFNyYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgVGVtcERlc3QpCnsKICAgICBjbXNIUFJPRklMRSBoSUNDOwogICAgIExQTFVUIEx1dDsKICAgICBCQ0hTV0FESlVTVFMgYmNoc3c7CiAgICAgY21zQ0lFeHlZIFdoaXRlUG50OwoKICAgICBiY2hzdy5CcmlnaHRuZXNzID0gQnJpZ2h0OwogICAgIGJjaHN3LkNvbnRyYXN0ICAgPSBDb250cmFzdDsKICAgICBiY2hzdy5IdWUgICAgICAgID0gSHVlOwogICAgIGJjaHN3LlNhdHVyYXRpb24gPSBTYXR1cmF0aW9uOwoKICAgICBjbXNXaGl0ZVBvaW50RnJvbVRlbXAoVGVtcFNyYywgICZXaGl0ZVBudCk7CiAgICAgY21zeHlZMlhZWigmYmNoc3cuV1BzcmMsICZXaGl0ZVBudCk7CgogICAgIGNtc1doaXRlUG9pbnRGcm9tVGVtcChUZW1wRGVzdCwgJldoaXRlUG50KTsKICAgICBjbXN4eVkyWFlaKCZiY2hzdy5XUGRlc3QsICZXaGl0ZVBudCk7CgogICAgICBoSUNDID0gX2Ntc0NyZWF0ZVByb2ZpbGVQbGFjZWhvbGRlcigpOwogICAgICAgaWYgKCFoSUNDKSAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FuJ3QgYWxsb2NhdGUKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgoKICAgICAgIGNtc1NldERldmljZUNsYXNzKGhJQ0MsICAgICAgaWNTaWdBYnN0cmFjdENsYXNzKTsKICAgICAgIGNtc1NldENvbG9yU3BhY2UoaElDQywgICAgICAgaWNTaWdMYWJEYXRhKTsKICAgICAgIGNtc1NldFBDUyhoSUNDLCAgICAgICAgICAgICAgaWNTaWdMYWJEYXRhKTsKCiAgICAgICBjbXNTZXRSZW5kZXJpbmdJbnRlbnQoaElDQywgIElOVEVOVF9QRVJDRVBUVUFMKTsKCgogICAgICAgLy8gQ3JlYXRlcyBhIExVVCB3aXRoIDNEIGdyaWQgb25seQogICAgICAgTHV0ID0gY21zQWxsb2NMVVQoKTsKCgogICAgICAgY21zQWxsb2MzREdyaWQoTHV0LCBuTFVUUG9pbnRzLCAzLCAzKTsKCiAgICAgICBpZiAoIWNtc1NhbXBsZTNER3JpZChMdXQsIGJjaHN3U2FtcGxlciwgKExQVk9JRCkgJmJjaHN3LCAwKSkgewoKICAgICAgICAgICAgICAgIC8vIFNob3VsZG4ndCByZWFjaCBoZXJlCiAgICAgICAgICAgICAgICBjbXNGcmVlTFVUKEx1dCk7CiAgICAgICAgICAgICAgICBjbXNDbG9zZVByb2ZpbGUoaElDQyk7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgIH0KCiAgICAgICAvLyBDcmVhdGUgdGFncwoKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ0RldmljZU1mZ0Rlc2NUYWcsICAgICAgKExQVk9JRCkgIihsY21zIGludGVybmFsKSIpOwogICAgICAgY21zQWRkVGFnKGhJQ0MsIGljU2lnUHJvZmlsZURlc2NyaXB0aW9uVGFnLCAoTFBWT0lEKSAibGNtcyBCQ0hTVyBhYnN0cmFjdCBwcm9maWxlIik7CiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdEZXZpY2VNb2RlbERlc2NUYWcsICAgIChMUFZPSUQpICJCQ0hTVyBidWlsdC1pbiIpOwoKICAgICAgIGNtc0FkZFRhZyhoSUNDLCBpY1NpZ01lZGlhV2hpdGVQb2ludFRhZywgKExQVk9JRCkgY21zRDUwX1hZWigpKTsKCiAgICAgICBjbXNBZGRUYWcoaElDQywgaWNTaWdBVG9CMFRhZywgKExQVk9JRCkgTHV0KTsKCiAgICAgICAvLyBMVVQgaXMgYWxyZWFkeSBvbiB2aXJ0dWFsIHByb2ZpbGUKICAgICAgIGNtc0ZyZWVMVVQoTHV0KTsKCiAgICAgICAvLyBPaywgZG9uZQogICAgICAgcmV0dXJuIGhJQ0M7Cgp9CgoKLy8gQ3JlYXRlcyBhIGZha2UgTlVMTCBwcm9maWxlLiBUaGlzIHByb2ZpbGUgcmV0dXJuIDEgY2hhbm5lbCBhcyBhbHdheXMgMC4KLy8gSXMgdXNlZnVsIG9ubHkgZm9yIGdhbXV0IGNoZWNraW5nIHRyaWNrcwoKY21zSFBST0ZJTEUgTENNU0VYUE9SVCBjbXNDcmVhdGVOVUxMUHJvZmlsZSh2b2lkKQp7CiAgICAgICAgY21zSFBST0ZJTEUgaFByb2ZpbGU7CiAgICAgICAgTFBMVVQgTHV0OwogICAgICAgIExQR0FNTUFUQUJMRSBFbXB0eVRhYjsKCiAgICAgICAgaFByb2ZpbGUgPSBfY21zQ3JlYXRlUHJvZmlsZVBsYWNlaG9sZGVyKCk7CiAgICAgICAgaWYgKCFoUHJvZmlsZSkgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbid0IGFsbG9jYXRlCiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAgICAgY21zU2V0RGV2aWNlQ2xhc3MoaFByb2ZpbGUsIGljU2lnT3V0cHV0Q2xhc3MpOwogICAgICAgIGNtc1NldENvbG9yU3BhY2UoaFByb2ZpbGUsICBpY1NpZ0dyYXlEYXRhKTsKICAgICAgICBjbXNTZXRQQ1MoaFByb2ZpbGUsICAgICAgICAgaWNTaWdMYWJEYXRhKTsKCgogICAgICAgLy8gQW4gZW1wdHkgTFVUcyBpcyBhbGwgd2UgbmVlZAogICAgICAgTHV0ID0gY21zQWxsb2NMVVQoKTsKICAgICAgIGlmIChMdXQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgICAgTHV0IC0+IElucHV0Q2hhbiA9IDM7CiAgICAgICBMdXQgLT4gT3V0cHV0Q2hhbiA9IDE7CgogICAgICAgRW1wdHlUYWIgPSBjbXNBbGxvY0dhbW1hKDIpOwogICAgICAgRW1wdHlUYWIgLT5HYW1tYVRhYmxlWzBdID0gMDsKICAgICAgIEVtcHR5VGFiIC0+R2FtbWFUYWJsZVsxXSA9IDA7CgogICAgICAgY21zQWxsb2NMaW5lYXJUYWJsZShMdXQsICZFbXB0eVRhYiwgMik7CgogICAgICAgY21zQWRkVGFnKGhQcm9maWxlLCBpY1NpZ0JUb0EwVGFnLCAoTFBWT0lEKSBMdXQpOwoKICAgICAgIGNtc0ZyZWVMVVQoTHV0KTsKICAgICAgIGNtc0ZyZWVHYW1tYShFbXB0eVRhYik7CgogICAgICAgcmV0dXJuIGhQcm9maWxlOwp9Cg==