LyoKICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKLy8gVGhpcyBmaWxlIGlzIGF2YWlsYWJsZSB1bmRlciBhbmQgZ292ZXJuZWQgYnkgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwovLyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KLy8gSG93ZXZlciwgdGhlIGZvbGxvd2luZyBub3RpY2UgYWNjb21wYW5pZWQgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhpcwovLyBmaWxlOgovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLwovLyAgTGl0dGxlIENvbG9yIE1hbmFnZW1lbnQgU3lzdGVtCi8vICBDb3B5cmlnaHQgKGMpIDE5OTgtMjAxNCBNYXJ0aSBNYXJpYSBTYWd1ZXIKLy8KLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nCi8vIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbgovLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlCi8vIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Ci8vCi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgovLwovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKLy8gRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPCi8vIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5ECi8vIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUKLy8gTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTgovLyBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04KLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCi8vCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vCgojaW5jbHVkZSAibGNtczJfaW50ZXJuYWwuaCIKCi8vIFRyYW5zZm9ybWF0aW9ucyBzdHVmZgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKI2RlZmluZSBERUZBVUxUX09CU0VSVkVSX0FEQVBUQVRJT05fU1RBVEUgMS4wCgovLyBUaGUgQ29udGV4dDAgb2JzZXJ2ZXIgYWRhcHRhdGlvbiBzdGF0ZS4KX2Ntc0FkYXB0YXRpb25TdGF0ZUNodW5rVHlwZSBfY21zQWRhcHRhdGlvblN0YXRlQ2h1bmsgPSB7IERFRkFVTFRfT0JTRVJWRVJfQURBUFRBVElPTl9TVEFURSB9OwoKLy8gSW5pdCBhbmQgZHVwbGljYXRlIG9ic2VydmVyIGFkYXB0YXRpb24gc3RhdGUKdm9pZCBfY21zQWxsb2NBZGFwdGF0aW9uU3RhdGVDaHVuayhzdHJ1Y3QgX2Ntc0NvbnRleHRfc3RydWN0KiBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IF9jbXNDb250ZXh0X3N0cnVjdCogc3JjKQp7CiAgICBzdGF0aWMgX2Ntc0FkYXB0YXRpb25TdGF0ZUNodW5rVHlwZSBBZGFwdGF0aW9uU3RhdGVDaHVuayA9IHsgREVGQVVMVF9PQlNFUlZFUl9BREFQVEFUSU9OX1NUQVRFIH07CiAgICB2b2lkKiBmcm9tOwoKICAgIGlmIChzcmMgIT0gTlVMTCkgewogICAgICAgIGZyb20gPSBzcmMgLT5jaHVua3NbQWRhcHRhdGlvblN0YXRlQ29udGV4dF07CiAgICB9CiAgICBlbHNlIHsKICAgICAgIGZyb20gPSAmQWRhcHRhdGlvblN0YXRlQ2h1bms7CiAgICB9CgogICAgY3R4IC0+Y2h1bmtzW0FkYXB0YXRpb25TdGF0ZUNvbnRleHRdID0gX2Ntc1N1YkFsbG9jRHVwKGN0eCAtPk1lbVBvb2wsIGZyb20sIHNpemVvZihfY21zQWRhcHRhdGlvblN0YXRlQ2h1bmtUeXBlKSk7Cn0KCgovLyBTZXRzIGFkYXB0YXRpb24gc3RhdGUgZm9yIGFic29sdXRlIGNvbG9yaW1ldHJpYyBpbnRlbnQgaW4gdGhlIGdpdmVuIGNvbnRleHQuICBBZGFwdGF0aW9uIHN0YXRlIGFwcGxpZXMgb24gYWxsCi8vIGJ1dCBjbXNDcmVhdGVFeHRlbmRlZFRyYW5zZm9ybVRIUigpLiAgTGl0dGxlIENNUyBjYW4gaGFuZGxlIGluY29tcGxldGUgYWRhcHRhdGlvbiBzdGF0ZXMuCmNtc0Zsb2F0NjROdW1iZXIgQ01TRVhQT1JUIGNtc1NldEFkYXB0YXRpb25TdGF0ZVRIUihjbXNDb250ZXh0IENvbnRleHRJRCwgY21zRmxvYXQ2NE51bWJlciBkKQp7CiAgICBjbXNGbG9hdDY0TnVtYmVyIHByZXY7CiAgICBfY21zQWRhcHRhdGlvblN0YXRlQ2h1bmtUeXBlKiBwdHIgPSAoX2Ntc0FkYXB0YXRpb25TdGF0ZUNodW5rVHlwZSopIF9jbXNDb250ZXh0R2V0Q2xpZW50Q2h1bmsoQ29udGV4dElELCBBZGFwdGF0aW9uU3RhdGVDb250ZXh0KTsKCiAgICAvLyBHZXQgcHJldmlvdXMgdmFsdWUgZm9yIHJldHVybgogICAgcHJldiA9IHB0ciAtPkFkYXB0YXRpb25TdGF0ZTsKCiAgICAvLyBTZXQgdGhlIHZhbHVlIGlmIGQgaXMgcG9zaXRpdmUgb3IgemVybwogICAgaWYgKGQgPj0gMC4wKSB7CgogICAgICAgIHB0ciAtPkFkYXB0YXRpb25TdGF0ZSA9IGQ7CiAgICB9CgogICAgLy8gQWx3YXlzIHJldHVybiBwcmV2aW91cyB2YWx1ZQogICAgcmV0dXJuIHByZXY7Cn0KCgovLyBUaGUgYWRhcHRhdGlvbiBzdGF0ZSBtYXkgYmUgZGVmYXVsdGVkIGJ5IHRoaXMgZnVuY3Rpb24uIElmIHlvdSBkb24ndCBsaWtlIGl0LCB1c2UgdGhlIGV4dGVuZGVkIHRyYW5zZm9ybSByb3V0aW5lCmNtc0Zsb2F0NjROdW1iZXIgQ01TRVhQT1JUIGNtc1NldEFkYXB0YXRpb25TdGF0ZShjbXNGbG9hdDY0TnVtYmVyIGQpCnsKICAgIHJldHVybiBjbXNTZXRBZGFwdGF0aW9uU3RhdGVUSFIoTlVMTCwgZCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovLyBBbGFybSBjb2RlcyBmb3IgMTYtYml0IHRyYW5zZm9ybWF0aW9ucywgYmVjYXVzZSB0aGUgZml4ZWQgcmFuZ2Ugb2YgY29udGFpbmVycyB0aGVyZSBhcmUKLy8gbm8gdmFsdWVzIGxlZnQgdG8gbWFyayBvdXQgb2YgZ2FtdXQuCgojZGVmaW5lIERFRkFVTFRfQUxBUk1fQ09ERVNfVkFMVUUgezB4N0YwMCwgMHg3RjAwLCAweDdGMDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDB9CgpfY21zQWxhcm1Db2Rlc0NodW5rVHlwZSBfY21zQWxhcm1Db2Rlc0NodW5rID0geyBERUZBVUxUX0FMQVJNX0NPREVTX1ZBTFVFIH07CgovLyBTZXRzIHRoZSBjb2RlcyB1c2VkIHRvIG1hcmsgb3V0LW91dC1nYW11dCBvbiBQcm9vZmluZyB0cmFuc2Zvcm1zIGZvciBhIGdpdmVuIGNvbnRleHQuIFZhbHVlcyBhcmUgbWVhbnQgdG8gYmUKLy8gZW5jb2RlZCBpbiAxNiBiaXRzLgp2b2lkIENNU0VYUE9SVCBjbXNTZXRBbGFybUNvZGVzVEhSKGNtc0NvbnRleHQgQ29udGV4dElELCBjb25zdCBjbXNVSW50MTZOdW1iZXIgQWxhcm1Db2Rlc1BbY21zTUFYQ0hBTk5FTFNdKQp7CiAgICBfY21zQWxhcm1Db2Rlc0NodW5rVHlwZSogQ29udGV4dEFsYXJtQ29kZXMgPSAoX2Ntc0FsYXJtQ29kZXNDaHVua1R5cGUqKSBfY21zQ29udGV4dEdldENsaWVudENodW5rKENvbnRleHRJRCwgQWxhcm1Db2Rlc0NvbnRleHQpOwoKICAgIF9jbXNBc3NlcnQoQ29udGV4dEFsYXJtQ29kZXMgIT0gTlVMTCk7IC8vIENhbid0IGhhcHBlbgoKICAgIG1lbWNweShDb250ZXh0QWxhcm1Db2Rlcy0+QWxhcm1Db2RlcywgQWxhcm1Db2Rlc1AsIHNpemVvZihDb250ZXh0QWxhcm1Db2Rlcy0+QWxhcm1Db2RlcykpOwp9CgovLyBHZXRzIHRoZSBjdXJyZW50IGNvZGVzIHVzZWQgdG8gbWFyayBvdXQtb3V0LWdhbXV0IG9uIFByb29maW5nIHRyYW5zZm9ybXMgZm9yIHRoZSBnaXZlbiBjb250ZXh0LgovLyBWYWx1ZXMgYXJlIG1lYW50IHRvIGJlIGVuY29kZWQgaW4gMTYgYml0cy4Kdm9pZCBDTVNFWFBPUlQgY21zR2V0QWxhcm1Db2Rlc1RIUihjbXNDb250ZXh0IENvbnRleHRJRCwgY21zVUludDE2TnVtYmVyIEFsYXJtQ29kZXNQW2Ntc01BWENIQU5ORUxTXSkKewogICAgX2Ntc0FsYXJtQ29kZXNDaHVua1R5cGUqIENvbnRleHRBbGFybUNvZGVzID0gKF9jbXNBbGFybUNvZGVzQ2h1bmtUeXBlKikgX2Ntc0NvbnRleHRHZXRDbGllbnRDaHVuayhDb250ZXh0SUQsIEFsYXJtQ29kZXNDb250ZXh0KTsKCiAgICBfY21zQXNzZXJ0KENvbnRleHRBbGFybUNvZGVzICE9IE5VTEwpOyAvLyBDYW4ndCBoYXBwZW4KCiAgICBtZW1jcHkoQWxhcm1Db2Rlc1AsIENvbnRleHRBbGFybUNvZGVzLT5BbGFybUNvZGVzLCBzaXplb2YoQ29udGV4dEFsYXJtQ29kZXMtPkFsYXJtQ29kZXMpKTsKfQoKdm9pZCBDTVNFWFBPUlQgY21zU2V0QWxhcm1Db2Rlcyhjb25zdCBjbXNVSW50MTZOdW1iZXIgTmV3QWxhcm1bY21zTUFYQ0hBTk5FTFNdKQp7CiAgICBfY21zQXNzZXJ0KE5ld0FsYXJtICE9IE5VTEwpOwoKICAgIGNtc1NldEFsYXJtQ29kZXNUSFIoTlVMTCwgTmV3QWxhcm0pOwp9Cgp2b2lkIENNU0VYUE9SVCBjbXNHZXRBbGFybUNvZGVzKGNtc1VJbnQxNk51bWJlciBPbGRBbGFybVtjbXNNQVhDSEFOTkVMU10pCnsKICAgIF9jbXNBc3NlcnQoT2xkQWxhcm0gIT0gTlVMTCk7CiAgICBjbXNHZXRBbGFybUNvZGVzVEhSKE5VTEwsIE9sZEFsYXJtKTsKfQoKCi8vIEluaXQgYW5kIGR1cGxpY2F0ZSBhbGFybSBjb2Rlcwp2b2lkIF9jbXNBbGxvY0FsYXJtQ29kZXNDaHVuayhzdHJ1Y3QgX2Ntc0NvbnRleHRfc3RydWN0KiBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIHNyYykKewogICAgc3RhdGljIF9jbXNBbGFybUNvZGVzQ2h1bmtUeXBlIEFsYXJtQ29kZXNDaHVuayA9IHsgREVGQVVMVF9BTEFSTV9DT0RFU19WQUxVRSB9OwogICAgdm9pZCogZnJvbTsKCiAgICBpZiAoc3JjICE9IE5VTEwpIHsKICAgICAgICBmcm9tID0gc3JjIC0+Y2h1bmtzW0FsYXJtQ29kZXNDb250ZXh0XTsKICAgIH0KICAgIGVsc2UgewogICAgICAgZnJvbSA9ICZBbGFybUNvZGVzQ2h1bms7CiAgICB9CgogICAgY3R4IC0+Y2h1bmtzW0FsYXJtQ29kZXNDb250ZXh0XSA9IF9jbXNTdWJBbGxvY0R1cChjdHggLT5NZW1Qb29sLCBmcm9tLCBzaXplb2YoX2Ntc0FsYXJtQ29kZXNDaHVua1R5cGUpKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8vIEdldCByaWQgb2YgdHJhbnNmb3JtIHJlc291cmNlcwp2b2lkIENNU0VYUE9SVCBjbXNEZWxldGVUcmFuc2Zvcm0oY21zSFRSQU5TRk9STSBoVHJhbnNmb3JtKQp7CiAgICBfY21zVFJBTlNGT1JNKiBwID0gKF9jbXNUUkFOU0ZPUk0qKSBoVHJhbnNmb3JtOwoKICAgIF9jbXNBc3NlcnQocCAhPSBOVUxMKTsKCiAgICBpZiAocCAtPiBHYW11dENoZWNrKQogICAgICAgIGNtc1BpcGVsaW5lRnJlZShwIC0+IEdhbXV0Q2hlY2spOwoKICAgIGlmIChwIC0+IEx1dCkKICAgICAgICBjbXNQaXBlbGluZUZyZWUocCAtPiBMdXQpOwoKICAgIGlmIChwIC0+SW5wdXRDb2xvcmFudCkKICAgICAgICBjbXNGcmVlTmFtZWRDb2xvckxpc3QocCAtPklucHV0Q29sb3JhbnQpOwoKICAgIGlmIChwIC0+IE91dHB1dENvbG9yYW50KQogICAgICAgIGNtc0ZyZWVOYW1lZENvbG9yTGlzdChwIC0+T3V0cHV0Q29sb3JhbnQpOwoKICAgIGlmIChwIC0+U2VxdWVuY2UpCiAgICAgICAgY21zRnJlZVByb2ZpbGVTZXF1ZW5jZURlc2NyaXB0aW9uKHAgLT5TZXF1ZW5jZSk7CgogICAgaWYgKHAgLT5Vc2VyRGF0YSkKICAgICAgICBwIC0+RnJlZVVzZXJEYXRhKHAgLT5Db250ZXh0SUQsIHAgLT5Vc2VyRGF0YSk7CgogICAgX2Ntc0ZyZWUocCAtPkNvbnRleHRJRCwgKHZvaWQgKikgcCk7Cn0KCi8vIEFwcGx5IHRyYW5zZm9ybS4Kdm9pZCBDTVNFWFBPUlQgY21zRG9UcmFuc2Zvcm0oY21zSFRSQU5TRk9STSAgVHJhbnNmb3JtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBJbnB1dEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogT3V0cHV0QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgU2l6ZSkKCnsKICAgIF9jbXNUUkFOU0ZPUk0qIHAgPSAoX2Ntc1RSQU5TRk9STSopIFRyYW5zZm9ybTsKCiAgICBwIC0+IHhmb3JtKHAsIElucHV0QnVmZmVyLCBPdXRwdXRCdWZmZXIsIFNpemUsIFNpemUpOwp9CgoKLy8gQXBwbHkgdHJhbnNmb3JtLgp2b2lkIENNU0VYUE9SVCBjbXNEb1RyYW5zZm9ybVN0cmlkZShjbXNIVFJBTlNGT1JNICBUcmFuc2Zvcm0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIElucHV0QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBPdXRwdXRCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBTaXplLCBjbXNVSW50MzJOdW1iZXIgU3RyaWRlKQoKewogICAgX2Ntc1RSQU5TRk9STSogcCA9IChfY21zVFJBTlNGT1JNKikgVHJhbnNmb3JtOwoKICAgIHAgLT4geGZvcm0ocCwgSW5wdXRCdWZmZXIsIE91dHB1dEJ1ZmZlciwgU2l6ZSwgU3RyaWRlKTsKfQoKCi8vIFRyYW5zZm9ybSByb3V0aW5lcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovLyBGbG9hdCB4Zm9ybSBjb252ZXJ0cyBmbG9hdHMuIFNpbmNlIHRoZXJlIGFyZSBubyBwZXJmb3JtYW5jZSBpc3N1ZXMsIG9uZSByb3V0aW5lIGRvZXMgYWxsIGpvYiwgaW5jbHVkaW5nIGdhbXV0IGNoZWNrLgovLyBOb3RlIHRoYXQgYmVjYXVzZSBleHRlbmRlZCByYW5nZSwgd2UgY2FuIHVzZSBhIC0xLjAgdmFsdWUgZm9yIG91dCBvZiBnYW11dCBpbiB0aGlzIGNhc2UuCnN0YXRpYwp2b2lkIEZsb2F0WEZPUk0oX2Ntc1RSQU5TRk9STSogcCwKICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIGluLAogICAgICAgICAgICAgICAgdm9pZCogb3V0LCBjbXNVSW50MzJOdW1iZXIgU2l6ZSwgY21zVUludDMyTnVtYmVyIFN0cmlkZSkKewogICAgY21zVUludDhOdW1iZXIqIGFjY3VtOwogICAgY21zVUludDhOdW1iZXIqIG91dHB1dDsKICAgIGNtc0Zsb2F0MzJOdW1iZXIgZkluW2Ntc01BWENIQU5ORUxTXSwgZk91dFtjbXNNQVhDSEFOTkVMU107CiAgICBjbXNGbG9hdDMyTnVtYmVyIE91dE9mR2FtdXQ7CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgajsKCiAgICBhY2N1bSAgPSAoY21zVUludDhOdW1iZXIqKSAgaW47CiAgICBvdXRwdXQgPSAoY21zVUludDhOdW1iZXIqKSAgb3V0OwoKICAgIGZvciAoaT0wOyBpIDwgU2l6ZTsgaSsrKSB7CgogICAgICAgIGFjY3VtID0gcCAtPiBGcm9tSW5wdXRGbG9hdChwLCBmSW4sIGFjY3VtLCBTdHJpZGUpOwoKICAgICAgICAvLyBBbnkgZ2FtdXQgY2hhY2sgdG8gZG8/CiAgICAgICAgaWYgKHAgLT5HYW11dENoZWNrICE9IE5VTEwpIHsKCiAgICAgICAgICAgIC8vIEV2YWx1YXRlIGdhbXV0IG1hcmtlci4KICAgICAgICAgICAgY21zUGlwZWxpbmVFdmFsRmxvYXQoIGZJbiwgJk91dE9mR2FtdXQsIHAgLT5HYW11dENoZWNrKTsKCiAgICAgICAgICAgIC8vIElzIGN1cnJlbnQgY29sb3Igb3V0IG9mIGdhbXV0PwogICAgICAgICAgICBpZiAoT3V0T2ZHYW11dCA+IDAuMCkgewoKICAgICAgICAgICAgICAgIC8vIENlcnRhaW5seSwgb3V0IG9mIGdhbXV0CiAgICAgICAgICAgICAgICBmb3IgKGo9MDsgaiA8IGNtc01BWENIQU5ORUxTOyBqKyspCiAgICAgICAgICAgICAgICAgICAgZk91dFtqXSA9IC0xLjA7CgogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLy8gTm8sIHByb2NlZWQgbm9ybWFsbHkKICAgICAgICAgICAgICAgIGNtc1BpcGVsaW5lRXZhbEZsb2F0KGZJbiwgZk91dCwgcCAtPiBMdXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewoKICAgICAgICAgICAgLy8gTm8gZ2FtdXQgY2hlY2sgYXQgYWxsCiAgICAgICAgICAgIGNtc1BpcGVsaW5lRXZhbEZsb2F0KGZJbiwgZk91dCwgcCAtPiBMdXQpOwogICAgICAgIH0KCiAgICAgICAgLy8gQmFjayB0byBhc2tlZCByZXByZXNlbnRhdGlvbgogICAgICAgIG91dHB1dCA9IHAgLT4gVG9PdXRwdXRGbG9hdChwLCBmT3V0LCBvdXRwdXQsIFN0cmlkZSk7CiAgICB9Cn0KCgpzdGF0aWMKdm9pZCBOdWxsRmxvYXRYRk9STShfY21zVFJBTlNGT1JNKiBwLAogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIGluLAogICAgICAgICAgICAgICAgICAgIHZvaWQqIG91dCwKICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgU2l6ZSwKICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgU3RyaWRlKQp7CiAgICBjbXNVSW50OE51bWJlciogYWNjdW07CiAgICBjbXNVSW50OE51bWJlciogb3V0cHV0OwogICAgY21zRmxvYXQzMk51bWJlciBmSW5bY21zTUFYQ0hBTk5FTFNdOwogICAgY21zVUludDMyTnVtYmVyIGksIG47CgogICAgYWNjdW0gID0gKGNtc1VJbnQ4TnVtYmVyKikgIGluOwogICAgb3V0cHV0ID0gKGNtc1VJbnQ4TnVtYmVyKikgIG91dDsKICAgIG4gPSBTaXplOwoKICAgIGZvciAoaT0wOyBpIDwgbjsgaSsrKSB7CgogICAgICAgIGFjY3VtICA9IHAgLT4gRnJvbUlucHV0RmxvYXQocCwgZkluLCBhY2N1bSwgU3RyaWRlKTsKICAgICAgICBvdXRwdXQgPSBwIC0+IFRvT3V0cHV0RmxvYXQocCwgZkluLCBvdXRwdXQsIFN0cmlkZSk7CiAgICB9Cn0KCi8vIDE2IGJpdCBwcmVjaXNpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8vIE51bGwgdHJhbnNmb3JtYXRpb24sIG9ubHkgYXBwbGllcyBmb3JtYXR0ZXJzLiBObyBjYWNo6QpzdGF0aWMKdm9pZCBOdWxsWEZPUk0oX2Ntc1RSQU5TRk9STSogcCwKICAgICAgICAgICAgICAgY29uc3Qgdm9pZCogaW4sCiAgICAgICAgICAgICAgIHZvaWQqIG91dCwgY21zVUludDMyTnVtYmVyIFNpemUsCiAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBTdHJpZGUpCnsKICAgIGNtc1VJbnQ4TnVtYmVyKiBhY2N1bTsKICAgIGNtc1VJbnQ4TnVtYmVyKiBvdXRwdXQ7CiAgICBjbXNVSW50MTZOdW1iZXIgd0luW2Ntc01BWENIQU5ORUxTXTsKICAgIGNtc1VJbnQzMk51bWJlciBpLCBuOwoKICAgIGFjY3VtICA9IChjbXNVSW50OE51bWJlciopICBpbjsKICAgIG91dHB1dCA9IChjbXNVSW50OE51bWJlciopICBvdXQ7CiAgICBuID0gU2l6ZTsgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZmZlciBsZW4KCiAgICBmb3IgKGk9MDsgaSA8IG47IGkrKykgewoKICAgICAgICBhY2N1bSAgPSBwIC0+IEZyb21JbnB1dChwLCB3SW4sIGFjY3VtLCBTdHJpZGUpOwogICAgICAgIG91dHB1dCA9IHAgLT4gVG9PdXRwdXQocCwgd0luLCBvdXRwdXQsIFN0cmlkZSk7CiAgICB9Cn0KCgovLyBObyBnYW11dCBjaGVjaywgbm8gY2FjaGUsIDE2IGJpdHMKc3RhdGljCnZvaWQgUHJlY2FsY3VsYXRlZFhGT1JNKF9jbXNUUkFOU0ZPUk0qIHAsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIGluLAogICAgICAgICAgICAgICAgICAgICAgICB2b2lkKiBvdXQsIGNtc1VJbnQzMk51bWJlciBTaXplLCBjbXNVSW50MzJOdW1iZXIgU3RyaWRlKQp7CiAgICByZWdpc3RlciBjbXNVSW50OE51bWJlciogYWNjdW07CiAgICByZWdpc3RlciBjbXNVSW50OE51bWJlciogb3V0cHV0OwogICAgY21zVUludDE2TnVtYmVyIHdJbltjbXNNQVhDSEFOTkVMU10sIHdPdXRbY21zTUFYQ0hBTk5FTFNdOwogICAgY21zVUludDMyTnVtYmVyIGksIG47CgogICAgYWNjdW0gID0gKGNtc1VJbnQ4TnVtYmVyKikgIGluOwogICAgb3V0cHV0ID0gKGNtc1VJbnQ4TnVtYmVyKikgIG91dDsKICAgIG4gPSBTaXplOwoKICAgIGZvciAoaT0wOyBpIDwgbjsgaSsrKSB7CgogICAgICAgIGFjY3VtID0gcCAtPiBGcm9tSW5wdXQocCwgd0luLCBhY2N1bSwgU3RyaWRlKTsKICAgICAgICBwIC0+THV0IC0+RXZhbDE2Rm4od0luLCB3T3V0LCBwIC0+IEx1dC0+RGF0YSk7CiAgICAgICAgb3V0cHV0ID0gcCAtPiBUb091dHB1dChwLCB3T3V0LCBvdXRwdXQsIFN0cmlkZSk7CiAgICB9Cn0KCgovLyBBdXhpbGlhcjogSGFuZGxlIHByZWNhbGN1bGF0ZWQgZ2FtdXQgY2hlY2suIFRoZSByZXRyaWV2YWwgb2YgY29udGV4dCBtYXkgYmUgYWxpdHRsZSBiaXQgc2xvdywgYnV0IHRoaXMgZnVuY3Rpb24gaXMgbm90IGNyaXRpY2FsLgpzdGF0aWMKdm9pZCBUcmFuc2Zvcm1PbmVQaXhlbFdpdGhHYW11dENoZWNrKF9jbXNUUkFOU0ZPUk0qIHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbXNVSW50MTZOdW1iZXIgd0luW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MTZOdW1iZXIgd091dFtdKQp7CiAgICBjbXNVSW50MTZOdW1iZXIgd091dE9mR2FtdXQ7CgogICAgcCAtPkdhbXV0Q2hlY2sgLT5FdmFsMTZGbih3SW4sICZ3T3V0T2ZHYW11dCwgcCAtPkdhbXV0Q2hlY2sgLT5EYXRhKTsKICAgIGlmICh3T3V0T2ZHYW11dCA+PSAxKSB7CgogICAgICAgIGNtc1VJbnQxNk51bWJlciBpOwogICAgICAgIF9jbXNBbGFybUNvZGVzQ2h1bmtUeXBlKiBDb250ZXh0QWxhcm1Db2RlcyA9IChfY21zQWxhcm1Db2Rlc0NodW5rVHlwZSopIF9jbXNDb250ZXh0R2V0Q2xpZW50Q2h1bmsocC0+Q29udGV4dElELCBBbGFybUNvZGVzQ29udGV4dCk7CgogICAgICAgIGZvciAoaT0wOyBpIDwgcCAtPkx1dC0+T3V0cHV0Q2hhbm5lbHM7IGkrKykgewoKICAgICAgICAgICAgd091dFtpXSA9IENvbnRleHRBbGFybUNvZGVzIC0+QWxhcm1Db2Rlc1tpXTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICAgICAgcCAtPkx1dCAtPkV2YWwxNkZuKHdJbiwgd091dCwgcCAtPiBMdXQtPkRhdGEpOwp9CgovLyBHYW11dCBjaGVjaywgTm8gY2FjaOksIDE2IGJpdHMuCnN0YXRpYwp2b2lkIFByZWNhbGN1bGF0ZWRYRk9STUdhbXV0Q2hlY2soX2Ntc1RSQU5TRk9STSogcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIGluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogb3V0LCBjbXNVSW50MzJOdW1iZXIgU2l6ZSwgY21zVUludDMyTnVtYmVyIFN0cmlkZSkKewogICAgY21zVUludDhOdW1iZXIqIGFjY3VtOwogICAgY21zVUludDhOdW1iZXIqIG91dHB1dDsKICAgIGNtc1VJbnQxNk51bWJlciB3SW5bY21zTUFYQ0hBTk5FTFNdLCB3T3V0W2Ntc01BWENIQU5ORUxTXTsKICAgIGNtc1VJbnQzMk51bWJlciBpLCBuOwoKICAgIGFjY3VtICA9IChjbXNVSW50OE51bWJlciopICBpbjsKICAgIG91dHB1dCA9IChjbXNVSW50OE51bWJlciopICBvdXQ7CiAgICBuID0gU2l6ZTsgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZmZlciBsZW4KCiAgICBmb3IgKGk9MDsgaSA8IG47IGkrKykgewoKICAgICAgICBhY2N1bSA9IHAgLT4gRnJvbUlucHV0KHAsIHdJbiwgYWNjdW0sIFN0cmlkZSk7CiAgICAgICAgVHJhbnNmb3JtT25lUGl4ZWxXaXRoR2FtdXRDaGVjayhwLCB3SW4sIHdPdXQpOwogICAgICAgIG91dHB1dCA9IHAgLT4gVG9PdXRwdXQocCwgd091dCwgb3V0cHV0LCBTdHJpZGUpOwogICAgfQp9CgoKLy8gTm8gZ2FtdXQgY2hlY2ssIENhY2jpLCAxNiBiaXRzLApzdGF0aWMKdm9pZCBDYWNoZWRYRk9STShfY21zVFJBTlNGT1JNKiBwLAogICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQqIGluLAogICAgICAgICAgICAgICAgIHZvaWQqIG91dCwgY21zVUludDMyTnVtYmVyIFNpemUsIGNtc1VJbnQzMk51bWJlciBTdHJpZGUpCnsKICAgIGNtc1VJbnQ4TnVtYmVyKiBhY2N1bTsKICAgIGNtc1VJbnQ4TnVtYmVyKiBvdXRwdXQ7CiAgICBjbXNVSW50MTZOdW1iZXIgd0luW2Ntc01BWENIQU5ORUxTXSwgd091dFtjbXNNQVhDSEFOTkVMU107CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgbjsKICAgIF9jbXNDQUNIRSBDYWNoZTsKCiAgICBhY2N1bSAgPSAoY21zVUludDhOdW1iZXIqKSAgaW47CiAgICBvdXRwdXQgPSAoY21zVUludDhOdW1iZXIqKSAgb3V0OwogICAgbiA9IFNpemU7ICAgICAgICAgICAgICAgICAgICAvLyBCdWZmZXIgbGVuCgogICAgLy8gRW1wdHkgYnVmZmVycyBmb3IgcXVpY2sgbWVtY21wCiAgICBtZW1zZXQod0luLCAgMCwgc2l6ZW9mKHdJbikpOwogICAgbWVtc2V0KHdPdXQsIDAsIHNpemVvZih3T3V0KSk7CgogICAgLy8gR2V0IGNvcHkgb2YgemVybyBjYWNoZQogICAgbWVtY3B5KCZDYWNoZSwgJnAgLT5DYWNoZSwgc2l6ZW9mKENhY2hlKSk7CgogICAgZm9yIChpPTA7IGkgPCBuOyBpKyspIHsKCiAgICAgICAgYWNjdW0gPSBwIC0+IEZyb21JbnB1dChwLCB3SW4sIGFjY3VtLCBTdHJpZGUpOwoKICAgICAgICBpZiAobWVtY21wKHdJbiwgQ2FjaGUuQ2FjaGVJbiwgc2l6ZW9mKENhY2hlLkNhY2hlSW4pKSA9PSAwKSB7CgogICAgICAgICAgICBtZW1jcHkod091dCwgQ2FjaGUuQ2FjaGVPdXQsIHNpemVvZihDYWNoZS5DYWNoZU91dCkpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKCiAgICAgICAgICAgIHAgLT5MdXQgLT5FdmFsMTZGbih3SW4sIHdPdXQsIHAgLT4gTHV0LT5EYXRhKTsKCiAgICAgICAgICAgIG1lbWNweShDYWNoZS5DYWNoZUluLCAgd0luLCAgc2l6ZW9mKENhY2hlLkNhY2hlSW4pKTsKICAgICAgICAgICAgbWVtY3B5KENhY2hlLkNhY2hlT3V0LCB3T3V0LCBzaXplb2YoQ2FjaGUuQ2FjaGVPdXQpKTsKICAgICAgICB9CgogICAgICAgIG91dHB1dCA9IHAgLT4gVG9PdXRwdXQocCwgd091dCwgb3V0cHV0LCBTdHJpZGUpOwogICAgfQoKfQoKCi8vIEFsbCB0aG9zZSBuaWNlIGZlYXR1cmVzIHRvZ2V0aGVyCnN0YXRpYwp2b2lkIENhY2hlZFhGT1JNR2FtdXRDaGVjayhfY21zVFJBTlNGT1JNKiBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkKiBpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogb3V0LCBjbXNVSW50MzJOdW1iZXIgU2l6ZSwgY21zVUludDMyTnVtYmVyIFN0cmlkZSkKewogICAgICAgY21zVUludDhOdW1iZXIqIGFjY3VtOwogICAgICAgY21zVUludDhOdW1iZXIqIG91dHB1dDsKICAgICAgIGNtc1VJbnQxNk51bWJlciB3SW5bY21zTUFYQ0hBTk5FTFNdLCB3T3V0W2Ntc01BWENIQU5ORUxTXTsKICAgICAgIGNtc1VJbnQzMk51bWJlciBpLCBuOwogICAgICAgX2Ntc0NBQ0hFIENhY2hlOwoKICAgICAgIGFjY3VtICA9IChjbXNVSW50OE51bWJlciopICBpbjsKICAgICAgIG91dHB1dCA9IChjbXNVSW50OE51bWJlciopICBvdXQ7CiAgICAgICBuID0gU2l6ZTsgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZmZlciBsZW4KCiAgICAgICAvLyBFbXB0eSBidWZmZXJzIGZvciBxdWljayBtZW1jbXAKICAgICAgIG1lbXNldCh3SW4sICAwLCBzaXplb2YoY21zVUludDE2TnVtYmVyKSAqIGNtc01BWENIQU5ORUxTKTsKICAgICAgIG1lbXNldCh3T3V0LCAwLCBzaXplb2YoY21zVUludDE2TnVtYmVyKSAqIGNtc01BWENIQU5ORUxTKTsKCiAgICAgICAvLyBHZXQgY29weSBvZiB6ZXJvIGNhY2hlCiAgICAgICBtZW1jcHkoJkNhY2hlLCAmcCAtPkNhY2hlLCBzaXplb2YoQ2FjaGUpKTsKCiAgICAgICBmb3IgKGk9MDsgaSA8IG47IGkrKykgewoKICAgICAgICAgICAgYWNjdW0gPSBwIC0+IEZyb21JbnB1dChwLCB3SW4sIGFjY3VtLCBTdHJpZGUpOwoKICAgICAgICAgICAgaWYgKG1lbWNtcCh3SW4sIENhY2hlLkNhY2hlSW4sIHNpemVvZihDYWNoZS5DYWNoZUluKSkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIG1lbWNweSh3T3V0LCBDYWNoZS5DYWNoZU91dCwgc2l6ZW9mKENhY2hlLkNhY2hlT3V0KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtT25lUGl4ZWxXaXRoR2FtdXRDaGVjayhwLCB3SW4sIHdPdXQpOwogICAgICAgICAgICAgICAgICAgIG1lbWNweShDYWNoZS5DYWNoZUluLCB3SW4sIHNpemVvZihDYWNoZS5DYWNoZUluKSk7CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KENhY2hlLkNhY2hlT3V0LCB3T3V0LCBzaXplb2YoQ2FjaGUuQ2FjaGVPdXQpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgb3V0cHV0ID0gcCAtPiBUb091dHB1dChwLCB3T3V0LCBvdXRwdXQsIFN0cmlkZSk7CiAgICAgICB9Cgp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovLyBMaXN0IG9mIHVzZWQtZGVmaW5lZCB0cmFuc2Zvcm0gZmFjdG9yaWVzCnR5cGVkZWYgc3RydWN0IF9jbXNUcmFuc2Zvcm1Db2xsZWN0aW9uX3N0IHsKCiAgICBfY21zVHJhbnNmb3JtRmFjdG9yeSAgRmFjdG9yeTsKICAgIHN0cnVjdCBfY21zVHJhbnNmb3JtQ29sbGVjdGlvbl9zdCAqTmV4dDsKCn0gX2Ntc1RyYW5zZm9ybUNvbGxlY3Rpb247CgovLyBUaGUgbGlua2VkIGxpc3QgaGVhZApfY21zVHJhbnNmb3JtUGx1Z2luQ2h1bmtUeXBlIF9jbXNUcmFuc2Zvcm1QbHVnaW5DaHVuayA9IHsgTlVMTCB9OwoKCi8vIER1cGxpY2F0ZXMgdGhlIHpvbmUgb2YgbWVtb3J5IHVzZWQgYnkgdGhlIHBsdWctaW4gaW4gdGhlIG5ldyBjb250ZXh0CnN0YXRpYwp2b2lkIER1cFBsdWdpblRyYW5zZm9ybUxpc3Qoc3RydWN0IF9jbXNDb250ZXh0X3N0cnVjdCogY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIHNyYykKewogICBfY21zVHJhbnNmb3JtUGx1Z2luQ2h1bmtUeXBlIG5ld0hlYWQgPSB7IE5VTEwgfTsKICAgX2Ntc1RyYW5zZm9ybUNvbGxlY3Rpb24qICBlbnRyeTsKICAgX2Ntc1RyYW5zZm9ybUNvbGxlY3Rpb24qICBBbnRlcmlvciA9IE5VTEw7CiAgIF9jbXNUcmFuc2Zvcm1QbHVnaW5DaHVua1R5cGUqIGhlYWQgPSAoX2Ntc1RyYW5zZm9ybVBsdWdpbkNodW5rVHlwZSopIHNyYy0+Y2h1bmtzW1RyYW5zZm9ybVBsdWdpbl07CgogICAgLy8gV2FsayB0aGUgbGlzdCBjb3B5aW5nIGFsbCBub2RlcwogICBmb3IgKGVudHJ5ID0gaGVhZC0+VHJhbnNmb3JtQ29sbGVjdGlvbjsKICAgICAgICBlbnRyeSAhPSBOVUxMOwogICAgICAgIGVudHJ5ID0gZW50cnkgLT5OZXh0KSB7CgogICAgICAgICAgICBfY21zVHJhbnNmb3JtQ29sbGVjdGlvbiAqbmV3RW50cnkgPSAoIF9jbXNUcmFuc2Zvcm1Db2xsZWN0aW9uICopIF9jbXNTdWJBbGxvY0R1cChjdHggLT5NZW1Qb29sLCBlbnRyeSwgc2l6ZW9mKF9jbXNUcmFuc2Zvcm1Db2xsZWN0aW9uKSk7CgogICAgICAgICAgICBpZiAobmV3RW50cnkgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgIC8vIFdlIHdhbnQgdG8ga2VlcCB0aGUgbGlua2VkIGxpc3Qgb3JkZXIsIHNvIHRoaXMgaXMgYSBsaXR0bGUgYml0IHRyaWNreQogICAgICAgICAgICBuZXdFbnRyeSAtPiBOZXh0ID0gTlVMTDsKICAgICAgICAgICAgaWYgKEFudGVyaW9yKQogICAgICAgICAgICAgICAgQW50ZXJpb3IgLT4gTmV4dCA9IG5ld0VudHJ5OwoKICAgICAgICAgICAgQW50ZXJpb3IgPSBuZXdFbnRyeTsKCiAgICAgICAgICAgIGlmIChuZXdIZWFkLlRyYW5zZm9ybUNvbGxlY3Rpb24gPT0gTlVMTCkKICAgICAgICAgICAgICAgIG5ld0hlYWQuVHJhbnNmb3JtQ29sbGVjdGlvbiA9IG5ld0VudHJ5OwogICAgfQoKICBjdHggLT5jaHVua3NbVHJhbnNmb3JtUGx1Z2luXSA9IF9jbXNTdWJBbGxvY0R1cChjdHgtPk1lbVBvb2wsICZuZXdIZWFkLCBzaXplb2YoX2Ntc1RyYW5zZm9ybVBsdWdpbkNodW5rVHlwZSkpOwp9Cgp2b2lkIF9jbXNBbGxvY1RyYW5zZm9ybVBsdWdpbkNodW5rKHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIGN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIHNyYykKewogICAgaWYgKHNyYyAhPSBOVUxMKSB7CgogICAgICAgIC8vIENvcHkgYWxsIGxpbmtlZCBsaXN0CiAgICAgICAgRHVwUGx1Z2luVHJhbnNmb3JtTGlzdChjdHgsIHNyYyk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBzdGF0aWMgX2Ntc1RyYW5zZm9ybVBsdWdpbkNodW5rVHlwZSBUcmFuc2Zvcm1QbHVnaW5DaHVua1R5cGUgPSB7IE5VTEwgfTsKICAgICAgICBjdHggLT5jaHVua3NbVHJhbnNmb3JtUGx1Z2luXSA9IF9jbXNTdWJBbGxvY0R1cChjdHggLT5NZW1Qb29sLCAmVHJhbnNmb3JtUGx1Z2luQ2h1bmtUeXBlLCBzaXplb2YoX2Ntc1RyYW5zZm9ybVBsdWdpbkNodW5rVHlwZSkpOwogICAgfQp9CgoKCi8vIFJlZ2lzdGVyIG5ldyB3YXlzIHRvIHRyYW5zZm9ybQpjbXNCb29sICBfY21zUmVnaXN0ZXJUcmFuc2Zvcm1QbHVnaW4oY21zQ29udGV4dCBDb250ZXh0SUQsIGNtc1BsdWdpbkJhc2UqIERhdGEpCnsKICAgIGNtc1BsdWdpblRyYW5zZm9ybSogUGx1Z2luID0gKGNtc1BsdWdpblRyYW5zZm9ybSopIERhdGE7CiAgICBfY21zVHJhbnNmb3JtQ29sbGVjdGlvbiogZmw7CiAgICBfY21zVHJhbnNmb3JtUGx1Z2luQ2h1bmtUeXBlKiBjdHggPSAoIF9jbXNUcmFuc2Zvcm1QbHVnaW5DaHVua1R5cGUqKSBfY21zQ29udGV4dEdldENsaWVudENodW5rKENvbnRleHRJRCxUcmFuc2Zvcm1QbHVnaW4pOwoKICAgIGlmIChEYXRhID09IE5VTEwpIHsKCiAgICAgICAgLy8gRnJlZSB0aGUgY2hhaW4uIE1lbW9yeSBpcyBzYWZlbHkgZnJlZWQgYXQgZXhpdAogICAgICAgIGN0eC0+VHJhbnNmb3JtQ29sbGVjdGlvbiA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgLy8gRmFjdG9yeSBjYWxsYmFjayBpcyByZXF1aXJlZAogICAgaWYgKFBsdWdpbiAtPkZhY3RvcnkgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKCiAgICBmbCA9IChfY21zVHJhbnNmb3JtQ29sbGVjdGlvbiopIF9jbXNQbHVnaW5NYWxsb2MoQ29udGV4dElELCBzaXplb2YoX2Ntc1RyYW5zZm9ybUNvbGxlY3Rpb24pKTsKICAgIGlmIChmbCA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CgogICAgLy8gQ29weSB0aGUgcGFyYW1ldGVycwogICAgZmwgLT5GYWN0b3J5ID0gUGx1Z2luIC0+RmFjdG9yeTsKCiAgICAvLyBLZWVwIGxpbmtlZCBsaXN0CiAgICBmbCAtPk5leHQgPSBjdHgtPlRyYW5zZm9ybUNvbGxlY3Rpb247CiAgICBjdHgtPlRyYW5zZm9ybUNvbGxlY3Rpb24gPSBmbDsKCiAgICAvLyBBbGwgaXMgb2sKICAgIHJldHVybiBUUlVFOwp9CgoKdm9pZCBDTVNFWFBPUlQgX2Ntc1NldFRyYW5zZm9ybVVzZXJEYXRhKHN0cnVjdCBfY21zdHJhbnNmb3JtX3N0cnVjdCAqQ01NY2FyZ28sIHZvaWQqIHB0ciwgX2Ntc0ZyZWVVc2VyRGF0YUZuIEZyZWVQcml2YXRlRGF0YUZuKQp7CiAgICBfY21zQXNzZXJ0KENNTWNhcmdvICE9IE5VTEwpOwogICAgQ01NY2FyZ28gLT5Vc2VyRGF0YSA9IHB0cjsKICAgIENNTWNhcmdvIC0+RnJlZVVzZXJEYXRhID0gRnJlZVByaXZhdGVEYXRhRm47Cn0KCi8vIHJldHVybnMgdGhlIHBvaW50ZXIgZGVmaW5lZCBieSB0aGUgcGx1Zy1pbiB0byBzdG9yZSBwcml2YXRlIGRhdGEKdm9pZCAqIENNU0VYUE9SVCBfY21zR2V0VHJhbnNmb3JtVXNlckRhdGEoc3RydWN0IF9jbXN0cmFuc2Zvcm1fc3RydWN0ICpDTU1jYXJnbykKewogICAgX2Ntc0Fzc2VydChDTU1jYXJnbyAhPSBOVUxMKTsKICAgIHJldHVybiBDTU1jYXJnbyAtPlVzZXJEYXRhOwp9CgovLyByZXR1cm5zIHRoZSBjdXJyZW50IGZvcm1hdHRlcnMKdm9pZCBDTVNFWFBPUlQgX2Ntc0dldFRyYW5zZm9ybUZvcm1hdHRlcnMxNihzdHJ1Y3QgX2Ntc3RyYW5zZm9ybV9zdHJ1Y3QgKkNNTWNhcmdvLCBjbXNGb3JtYXR0ZXIxNiogRnJvbUlucHV0LCBjbXNGb3JtYXR0ZXIxNiogVG9PdXRwdXQpCnsKICAgICBfY21zQXNzZXJ0KENNTWNhcmdvICE9IE5VTEwpOwogICAgIGlmIChGcm9tSW5wdXQpICpGcm9tSW5wdXQgPSBDTU1jYXJnbyAtPkZyb21JbnB1dDsKICAgICBpZiAoVG9PdXRwdXQpICAqVG9PdXRwdXQgID0gQ01NY2FyZ28gLT5Ub091dHB1dDsKfQoKdm9pZCBDTVNFWFBPUlQgX2Ntc0dldFRyYW5zZm9ybUZvcm1hdHRlcnNGbG9hdChzdHJ1Y3QgX2Ntc3RyYW5zZm9ybV9zdHJ1Y3QgKkNNTWNhcmdvLCBjbXNGb3JtYXR0ZXJGbG9hdCogRnJvbUlucHV0LCBjbXNGb3JtYXR0ZXJGbG9hdCogVG9PdXRwdXQpCnsKICAgICBfY21zQXNzZXJ0KENNTWNhcmdvICE9IE5VTEwpOwogICAgIGlmIChGcm9tSW5wdXQpICpGcm9tSW5wdXQgPSBDTU1jYXJnbyAtPkZyb21JbnB1dEZsb2F0OwogICAgIGlmIChUb091dHB1dCkgICpUb091dHB1dCAgPSBDTU1jYXJnbyAtPlRvT3V0cHV0RmxvYXQ7Cn0KCgovLyBBbGxvY2F0ZSB0cmFuc2Zvcm0gc3RydWN0IGFuZCBzZXQgaXQgdG8gZGVmYXVsdHMuIEFzayB0aGUgb3B0aW1pemF0aW9uIHBsdWctaW4gYWJvdXQgaWYgdGhvc2UgZm9ybWF0cyBhcmUgcHJvcGVyCi8vIGZvciBzZXBhcmF0ZWQgdHJhbnNmb3Jtcy4gSWYgdGhpcyBpcyB0aGUgY2FzZSwKc3RhdGljCl9jbXNUUkFOU0ZPUk0qIEFsbG9jRW1wdHlUcmFuc2Zvcm0oY21zQ29udGV4dCBDb250ZXh0SUQsIGNtc1BpcGVsaW5lKiBsdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIEludGVudCwgY21zVUludDMyTnVtYmVyKiBJbnB1dEZvcm1hdCwgY21zVUludDMyTnVtYmVyKiBPdXRwdXRGb3JtYXQsIGNtc1VJbnQzMk51bWJlciogZHdGbGFncykKewogICAgIF9jbXNUcmFuc2Zvcm1QbHVnaW5DaHVua1R5cGUqIGN0eCA9ICggX2Ntc1RyYW5zZm9ybVBsdWdpbkNodW5rVHlwZSopIF9jbXNDb250ZXh0R2V0Q2xpZW50Q2h1bmsoQ29udGV4dElELCBUcmFuc2Zvcm1QbHVnaW4pOwogICAgIF9jbXNUcmFuc2Zvcm1Db2xsZWN0aW9uKiBQbHVnaW47CgogICAgICAgLy8gQWxsb2NhdGUgbmVlZGVkIG1lbW9yeQogICAgICAgX2Ntc1RSQU5TRk9STSogcCA9IChfY21zVFJBTlNGT1JNKilfY21zTWFsbG9jWmVybyhDb250ZXh0SUQsIHNpemVvZihfY21zVFJBTlNGT1JNKSk7CiAgICAgICBpZiAoIXApIHJldHVybiBOVUxMOwoKICAgICAgIC8vIFN0b3JlIHRoZSBwcm9wb3NlZCBwaXBlbGluZQogICAgICAgcC0+THV0ID0gbHV0OwoKICAgICAgIC8vIExldCdzIHNlZSBpZiBhbnkgcGx1Zy1pbiB3YW50IHRvIGRvIHRoZSB0cmFuc2Zvcm0gYnkgaXRzZWxmCiAgICAgICBpZiAocC0+THV0ICE9IE5VTEwpIHsKCiAgICAgICAgICAgICAgZm9yIChQbHVnaW4gPSBjdHgtPlRyYW5zZm9ybUNvbGxlY3Rpb247CiAgICAgICAgICAgICAgICAgICAgIFBsdWdpbiAhPSBOVUxMOwogICAgICAgICAgICAgICAgICAgICBQbHVnaW4gPSBQbHVnaW4tPk5leHQpIHsKCiAgICAgICAgICAgICAgICAgICAgIGlmIChQbHVnaW4tPkZhY3RvcnkoJnAtPnhmb3JtLCAmcC0+VXNlckRhdGEsICZwLT5GcmVlVXNlckRhdGEsICZwLT5MdXQsIElucHV0Rm9ybWF0LCBPdXRwdXRGb3JtYXQsIGR3RmxhZ3MpKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGFzdCBwbHVnaW4gaW4gdGhlIGRlY2xhcmF0aW9uIG9yZGVyIHRha2VzIGNvbnRyb2wuIFdlIGp1c3Qga2VlcAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIG9yaWdpbmFsIHBhcmFtZXRlcnMgYXMgYSBsb2dnaW5nLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB0aGF0IGNtc0ZMQUdTX0NBTl9DSEFOR0VfRk9STUFUVEVSIGlzIG5vdCBzZXQsIHNvIGJ5IGRlZmF1bHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuIG9wdGltaXplZCB0cmFuc2Zvcm0gaXMgbm90IHJldXNhYmxlLiBUaGUgcGx1Zy1pbiBjYW4sIGhvd2V2ZXIsIGNoYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGZsYWdzIGFuZCBtYWtlIGl0IHN1aXRhYmxlLgoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAtPkNvbnRleHRJRCA9IENvbnRleHRJRDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAtPklucHV0Rm9ybWF0ID0gKklucHV0Rm9ybWF0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcC0+T3V0cHV0Rm9ybWF0ID0gKk91dHB1dEZvcm1hdDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAtPmR3T3JpZ2luYWxGbGFncyA9ICpkd0ZsYWdzOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpbGwgdGhlIGZvcm1hdHRlcnMganVzdCBpbiBjYXNlIHRoZSBvcHRpbWl6ZWQgcm91dGluZSBpcyBpbnRlcmVzdGVkLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm8gZXJyb3IgaXMgdGhyb3duIGlmIHRoZSBmb3JtYXR0ZXIgZG9lc24ndCBleGlzdC4gSXQgaXMgdXAgdG8gdGhlIG9wdGltaXphdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmFjdG9yeSB0byBkZWNpZGUgd2hhdCB0byBkbyBpbiB0aG9zZSBjYXNlcy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAtPkZyb21JbnB1dCA9IF9jbXNHZXRGb3JtYXR0ZXIoQ29udGV4dElELCAqSW5wdXRGb3JtYXQsIGNtc0Zvcm1hdHRlcklucHV0LCBDTVNfUEFDS19GTEFHU18xNkJJVFMpLkZtdDE2OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcC0+VG9PdXRwdXQgPSBfY21zR2V0Rm9ybWF0dGVyKENvbnRleHRJRCwgKk91dHB1dEZvcm1hdCwgY21zRm9ybWF0dGVyT3V0cHV0LCBDTVNfUEFDS19GTEFHU18xNkJJVFMpLkZtdDE2OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcC0+RnJvbUlucHV0RmxvYXQgPSBfY21zR2V0Rm9ybWF0dGVyKENvbnRleHRJRCwgKklucHV0Rm9ybWF0LCBjbXNGb3JtYXR0ZXJJbnB1dCwgQ01TX1BBQ0tfRkxBR1NfRkxPQVQpLkZtdEZsb2F0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcC0+VG9PdXRwdXRGbG9hdCA9IF9jbXNHZXRGb3JtYXR0ZXIoQ29udGV4dElELCAqT3V0cHV0Rm9ybWF0LCBjbXNGb3JtYXR0ZXJPdXRwdXQsIENNU19QQUNLX0ZMQUdTX0ZMT0FUKS5GbXRGbG9hdDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcDsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gTm90IHN1aXRhYmxlIGZvciB0aGUgdHJhbnNmb3JtIHBsdWctaW4sIGxldCdzIGNoZWNrICB0aGUgcGlwZWxpbmUgcGx1Zy1pbgogICAgICAgICAgICAgIF9jbXNPcHRpbWl6ZVBpcGVsaW5lKENvbnRleHRJRCwgJnAtPkx1dCwgSW50ZW50LCBJbnB1dEZvcm1hdCwgT3V0cHV0Rm9ybWF0LCBkd0ZsYWdzKTsKICAgICAgIH0KCiAgICAvLyBDaGVjayB3aGF0ZXZlciB0aGlzIGlzIGEgdHJ1ZSBmbG9hdGluZyBwb2ludCB0cmFuc2Zvcm0KICAgIGlmIChfY21zRm9ybWF0dGVySXNGbG9hdCgqSW5wdXRGb3JtYXQpICYmIF9jbXNGb3JtYXR0ZXJJc0Zsb2F0KCpPdXRwdXRGb3JtYXQpKSB7CgogICAgICAgIC8vIEdldCBmb3JtYXR0ZXIgZnVuY3Rpb24gYWx3YXlzIHJldHVybiBhIHZhbGlkIHVuaW9uLCBidXQgdGhlIGNvbnRlbnRzIG9mIHRoaXMgdW5pb24gbWF5IGJlIE5VTEwuCiAgICAgICAgcCAtPkZyb21JbnB1dEZsb2F0ID0gX2Ntc0dldEZvcm1hdHRlcihDb250ZXh0SUQsICpJbnB1dEZvcm1hdCwgIGNtc0Zvcm1hdHRlcklucHV0LCBDTVNfUEFDS19GTEFHU19GTE9BVCkuRm10RmxvYXQ7CiAgICAgICAgcCAtPlRvT3V0cHV0RmxvYXQgID0gX2Ntc0dldEZvcm1hdHRlcihDb250ZXh0SUQsICpPdXRwdXRGb3JtYXQsIGNtc0Zvcm1hdHRlck91dHB1dCwgQ01TX1BBQ0tfRkxBR1NfRkxPQVQpLkZtdEZsb2F0OwogICAgICAgICpkd0ZsYWdzIHw9IGNtc0ZMQUdTX0NBTl9DSEFOR0VfRk9STUFUVEVSOwoKICAgICAgICBpZiAocCAtPkZyb21JbnB1dEZsb2F0ID09IE5VTEwgfHwgcCAtPlRvT3V0cHV0RmxvYXQgPT0gTlVMTCkgewoKICAgICAgICAgICAgY21zU2lnbmFsRXJyb3IoQ29udGV4dElELCBjbXNFUlJPUl9VTktOT1dOX0VYVEVOU0lPTiwgIlVuc3VwcG9ydGVkIHJhc3RlciBmb3JtYXQiKTsKICAgICAgICAgICAgX2Ntc0ZyZWUoQ29udGV4dElELCBwKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQoKICAgICAgICBpZiAoKmR3RmxhZ3MgJiBjbXNGTEFHU19OVUxMVFJBTlNGT1JNKSB7CgogICAgICAgICAgICBwIC0+eGZvcm0gPSBOdWxsRmxvYXRYRk9STTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8vIEZsb2F0IHRyYW5zZm9ybXMgZG9uJ3QgdXNlIGNhY2jpLCBhbHdheXMgYXJlIG5vbi1OVUxMCiAgICAgICAgICAgIHAgLT54Zm9ybSA9IEZsb2F0WEZPUk07CiAgICAgICAgfQoKICAgIH0KICAgIGVsc2UgewoKICAgICAgICBpZiAoKklucHV0Rm9ybWF0ID09IDAgJiYgKk91dHB1dEZvcm1hdCA9PSAwKSB7CiAgICAgICAgICAgIHAgLT5Gcm9tSW5wdXQgPSBwIC0+VG9PdXRwdXQgPSBOVUxMOwogICAgICAgICAgICAqZHdGbGFncyB8PSBjbXNGTEFHU19DQU5fQ0hBTkdFX0ZPUk1BVFRFUjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CgogICAgICAgICAgICBpbnQgQnl0ZXNQZXJQaXhlbElucHV0OwoKICAgICAgICAgICAgcCAtPkZyb21JbnB1dCA9IF9jbXNHZXRGb3JtYXR0ZXIoQ29udGV4dElELCAqSW5wdXRGb3JtYXQsICBjbXNGb3JtYXR0ZXJJbnB1dCwgQ01TX1BBQ0tfRkxBR1NfMTZCSVRTKS5GbXQxNjsKICAgICAgICAgICAgcCAtPlRvT3V0cHV0ICA9IF9jbXNHZXRGb3JtYXR0ZXIoQ29udGV4dElELCAqT3V0cHV0Rm9ybWF0LCBjbXNGb3JtYXR0ZXJPdXRwdXQsIENNU19QQUNLX0ZMQUdTXzE2QklUUykuRm10MTY7CgogICAgICAgICAgICBpZiAocCAtPkZyb21JbnB1dCA9PSBOVUxMIHx8IHAgLT5Ub091dHB1dCA9PSBOVUxMKSB7CgogICAgICAgICAgICAgICAgY21zU2lnbmFsRXJyb3IoQ29udGV4dElELCBjbXNFUlJPUl9VTktOT1dOX0VYVEVOU0lPTiwgIlVuc3VwcG9ydGVkIHJhc3RlciBmb3JtYXQiKTsKICAgICAgICAgICAgICAgIF9jbXNGcmVlKENvbnRleHRJRCwgcCk7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQnl0ZXNQZXJQaXhlbElucHV0ID0gVF9CWVRFUyhwIC0+SW5wdXRGb3JtYXQpOwogICAgICAgICAgICBpZiAoQnl0ZXNQZXJQaXhlbElucHV0ID09IDAgfHwgQnl0ZXNQZXJQaXhlbElucHV0ID49IDIpCiAgICAgICAgICAgICAgICAgICAqZHdGbGFncyB8PSBjbXNGTEFHU19DQU5fQ0hBTkdFX0ZPUk1BVFRFUjsKCiAgICAgICAgfQoKICAgICAgICBpZiAoKmR3RmxhZ3MgJiBjbXNGTEFHU19OVUxMVFJBTlNGT1JNKSB7CgogICAgICAgICAgICBwIC0+eGZvcm0gPSBOdWxsWEZPUk07CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBpZiAoKmR3RmxhZ3MgJiBjbXNGTEFHU19OT0NBQ0hFKSB7CgogICAgICAgICAgICAgICAgaWYgKCpkd0ZsYWdzICYgY21zRkxBR1NfR0FNVVRDSEVDSykKICAgICAgICAgICAgICAgICAgICBwIC0+eGZvcm0gPSBQcmVjYWxjdWxhdGVkWEZPUk1HYW11dENoZWNrOyAgLy8gR2FtdXQgY2hlY2ssIG5vIGNhY2jpCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcCAtPnhmb3JtID0gUHJlY2FsY3VsYXRlZFhGT1JNOyAgLy8gTm8gY2FjaOksIG5vIGdhbXV0IGNoZWNrCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CgogICAgICAgICAgICAgICAgaWYgKCpkd0ZsYWdzICYgY21zRkxBR1NfR0FNVVRDSEVDSykKICAgICAgICAgICAgICAgICAgICBwIC0+eGZvcm0gPSBDYWNoZWRYRk9STUdhbXV0Q2hlY2s7ICAgIC8vIEdhbXV0IGNoZWNrLCBjYWNo6QogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHAgLT54Zm9ybSA9IENhY2hlZFhGT1JNOyAgLy8gTm8gZ2FtdXQgY2hlY2ssIGNhY2jpCgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHAgLT5JbnB1dEZvcm1hdCAgICAgPSAqSW5wdXRGb3JtYXQ7CiAgICBwIC0+T3V0cHV0Rm9ybWF0ICAgID0gKk91dHB1dEZvcm1hdDsKICAgIHAgLT5kd09yaWdpbmFsRmxhZ3MgPSAqZHdGbGFnczsKICAgIHAgLT5Db250ZXh0SUQgICAgICAgPSBDb250ZXh0SUQ7CiAgICBwIC0+VXNlckRhdGEgICAgICAgID0gTlVMTDsKICAgIHJldHVybiBwOwp9CgpzdGF0aWMKY21zQm9vbCBHZXRYRm9ybUNvbG9yU3BhY2VzKGludCBuUHJvZmlsZXMsIGNtc0hQUk9GSUxFIGhQcm9maWxlc1tdLCBjbXNDb2xvclNwYWNlU2lnbmF0dXJlKiBJbnB1dCwgY21zQ29sb3JTcGFjZVNpZ25hdHVyZSogT3V0cHV0KQp7CiAgICBjbXNDb2xvclNwYWNlU2lnbmF0dXJlIENvbG9yU3BhY2VJbiwgQ29sb3JTcGFjZU91dDsKICAgIGNtc0NvbG9yU3BhY2VTaWduYXR1cmUgUG9zdENvbG9yU3BhY2U7CiAgICBpbnQgaTsKCiAgICBpZiAoblByb2ZpbGVzIDw9IDApIHJldHVybiBGQUxTRTsKICAgIGlmIChoUHJvZmlsZXNbMF0gPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgICpJbnB1dCA9IFBvc3RDb2xvclNwYWNlID0gY21zR2V0Q29sb3JTcGFjZShoUHJvZmlsZXNbMF0pOwoKICAgIGZvciAoaT0wOyBpIDwgblByb2ZpbGVzOyBpKyspIHsKCiAgICAgICAgY21zUHJvZmlsZUNsYXNzU2lnbmF0dXJlIGNsczsKICAgICAgICBjbXNIUFJPRklMRSBoUHJvZmlsZSA9IGhQcm9maWxlc1tpXTsKCiAgICAgICAgaW50IGxJc0lucHV0ID0gKFBvc3RDb2xvclNwYWNlICE9IGNtc1NpZ1hZWkRhdGEpICYmCiAgICAgICAgICAgICAgICAgICAgICAgKFBvc3RDb2xvclNwYWNlICE9IGNtc1NpZ0xhYkRhdGEpOwoKICAgICAgICBpZiAoaFByb2ZpbGUgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgICAgICBjbHMgPSBjbXNHZXREZXZpY2VDbGFzcyhoUHJvZmlsZSk7CgogICAgICAgIGlmIChjbHMgPT0gY21zU2lnTmFtZWRDb2xvckNsYXNzKSB7CgogICAgICAgICAgICBDb2xvclNwYWNlSW4gICAgPSBjbXNTaWcxY29sb3JEYXRhOwogICAgICAgICAgICBDb2xvclNwYWNlT3V0ICAgPSAoblByb2ZpbGVzID4gMSkgPyBjbXNHZXRQQ1MoaFByb2ZpbGUpIDogY21zR2V0Q29sb3JTcGFjZShoUHJvZmlsZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICBpZiAobElzSW5wdXQgfHwgKGNscyA9PSBjbXNTaWdMaW5rQ2xhc3MpKSB7CgogICAgICAgICAgICBDb2xvclNwYWNlSW4gICAgPSBjbXNHZXRDb2xvclNwYWNlKGhQcm9maWxlKTsKICAgICAgICAgICAgQ29sb3JTcGFjZU91dCAgID0gY21zR2V0UENTKGhQcm9maWxlKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgQ29sb3JTcGFjZUluICAgID0gY21zR2V0UENTKGhQcm9maWxlKTsKICAgICAgICAgICAgQ29sb3JTcGFjZU91dCAgID0gY21zR2V0Q29sb3JTcGFjZShoUHJvZmlsZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaT09MCkKICAgICAgICAgICAgKklucHV0ID0gQ29sb3JTcGFjZUluOwoKICAgICAgICBQb3N0Q29sb3JTcGFjZSA9IENvbG9yU3BhY2VPdXQ7CiAgICB9CgogICAgKk91dHB1dCA9IFBvc3RDb2xvclNwYWNlOwoKICAgIHJldHVybiBUUlVFOwp9CgovLyBDaGVjayBjb2xvcnNwYWNlCnN0YXRpYwpjbXNCb29sICBJc1Byb3BlckNvbG9yU3BhY2UoY21zQ29sb3JTcGFjZVNpZ25hdHVyZSBDaGVjaywgY21zVUludDMyTnVtYmVyIGR3Rm9ybWF0KQp7CiAgICBpbnQgU3BhY2UxID0gVF9DT0xPUlNQQUNFKGR3Rm9ybWF0KTsKICAgIGludCBTcGFjZTIgPSBfY21zTENNU2NvbG9yU3BhY2UoQ2hlY2spOwoKICAgIGlmIChTcGFjZTEgPT0gUFRfQU5ZKSByZXR1cm4gVFJVRTsKICAgIGlmIChTcGFjZTEgPT0gU3BhY2UyKSByZXR1cm4gVFJVRTsKCiAgICBpZiAoU3BhY2UxID09IFBUX0xhYlYyICYmIFNwYWNlMiA9PSBQVF9MYWIpIHJldHVybiBUUlVFOwogICAgaWYgKFNwYWNlMSA9PSBQVF9MYWIgICAmJiBTcGFjZTIgPT0gUFRfTGFiVjIpIHJldHVybiBUUlVFOwoKICAgIHJldHVybiBGQUxTRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljCnZvaWQgU2V0V2hpdGVQb2ludChjbXNDSUVYWVoqIHd0UHQsIGNvbnN0IGNtc0NJRVhZWiogc3JjKQp7CiAgICBpZiAoc3JjID09IE5VTEwpIHsKICAgICAgICB3dFB0IC0+WCA9IGNtc0Q1MFg7CiAgICAgICAgd3RQdCAtPlkgPSBjbXNENTBZOwogICAgICAgIHd0UHQgLT5aID0gY21zRDUwWjsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHd0UHQgLT5YID0gc3JjLT5YOwogICAgICAgIHd0UHQgLT5ZID0gc3JjLT5ZOwogICAgICAgIHd0UHQgLT5aID0gc3JjLT5aOwogICAgfQoKfQoKLy8gTmV3IHRvIGxjbXMgMi4wIC0tIGhhdmUgYWxsIHBhcmFtZXRlcnMgYXZhaWxhYmxlLgpjbXNIVFJBTlNGT1JNIENNU0VYUE9SVCBjbXNDcmVhdGVFeHRlbmRlZFRyYW5zZm9ybShjbXNDb250ZXh0IENvbnRleHRJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIG5Qcm9maWxlcywgY21zSFBST0ZJTEUgaFByb2ZpbGVzW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0Jvb2wgIEJQQ1tdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgSW50ZW50c1tdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNGbG9hdDY0TnVtYmVyIEFkYXB0YXRpb25TdGF0ZXNbXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zSFBST0ZJTEUgaEdhbXV0UHJvZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIG5HYW11dFBDU3Bvc2l0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgSW5wdXRGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBPdXRwdXRGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBkd0ZsYWdzKQp7CiAgICBfY21zVFJBTlNGT1JNKiB4Zm9ybTsKICAgIGNtc0NvbG9yU3BhY2VTaWduYXR1cmUgRW50cnlDb2xvclNwYWNlOwogICAgY21zQ29sb3JTcGFjZVNpZ25hdHVyZSBFeGl0Q29sb3JTcGFjZTsKICAgIGNtc1BpcGVsaW5lKiBMdXQ7CiAgICBjbXNVSW50MzJOdW1iZXIgTGFzdEludGVudCA9IEludGVudHNbblByb2ZpbGVzLTFdOwoKICAgIC8vIElmIGl0IGlzIGEgZmFrZSB0cmFuc2Zvcm0KICAgIGlmIChkd0ZsYWdzICYgY21zRkxBR1NfTlVMTFRSQU5TRk9STSkKICAgIHsKICAgICAgICByZXR1cm4gQWxsb2NFbXB0eVRyYW5zZm9ybShDb250ZXh0SUQsIE5VTEwsIElOVEVOVF9QRVJDRVBUVUFMLCAmSW5wdXRGb3JtYXQsICZPdXRwdXRGb3JtYXQsICZkd0ZsYWdzKTsKICAgIH0KCiAgICAvLyBJZiBnYW11dCBjaGVjayBpcyByZXF1ZXN0ZWQsIG1ha2Ugc3VyZSB3ZSBoYXZlIGEgZ2FtdXQgcHJvZmlsZQogICAgaWYgKGR3RmxhZ3MgJiBjbXNGTEFHU19HQU1VVENIRUNLKSB7CiAgICAgICAgaWYgKGhHYW11dFByb2ZpbGUgPT0gTlVMTCkgZHdGbGFncyAmPSB+Y21zRkxBR1NfR0FNVVRDSEVDSzsKICAgIH0KCiAgICAvLyBPbiBmbG9hdGluZyBwb2ludCB0cmFuc2Zvcm1zLCBpbmhpYml0IGNhY2hlCiAgICBpZiAoX2Ntc0Zvcm1hdHRlcklzRmxvYXQoSW5wdXRGb3JtYXQpIHx8IF9jbXNGb3JtYXR0ZXJJc0Zsb2F0KE91dHB1dEZvcm1hdCkpCiAgICAgICAgZHdGbGFncyB8PSBjbXNGTEFHU19OT0NBQ0hFOwoKICAgIC8vIE1hcmsgZW50cnkvZXhpdCBzcGFjZXMKICAgIGlmICghR2V0WEZvcm1Db2xvclNwYWNlcyhuUHJvZmlsZXMsIGhQcm9maWxlcywgJkVudHJ5Q29sb3JTcGFjZSwgJkV4aXRDb2xvclNwYWNlKSkgewogICAgICAgIGNtc1NpZ25hbEVycm9yKENvbnRleHRJRCwgY21zRVJST1JfTlVMTCwgIk5VTEwgaW5wdXQgcHJvZmlsZXMgb24gdHJhbnNmb3JtIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLy8gQ2hlY2sgaWYgcHJvcGVyIGNvbG9yc3BhY2VzCiAgICBpZiAoIUlzUHJvcGVyQ29sb3JTcGFjZShFbnRyeUNvbG9yU3BhY2UsIElucHV0Rm9ybWF0KSkgewogICAgICAgIGNtc1NpZ25hbEVycm9yKENvbnRleHRJRCwgY21zRVJST1JfQ09MT1JTUEFDRV9DSEVDSywgIldyb25nIGlucHV0IGNvbG9yIHNwYWNlIG9uIHRyYW5zZm9ybSIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmICghSXNQcm9wZXJDb2xvclNwYWNlKEV4aXRDb2xvclNwYWNlLCBPdXRwdXRGb3JtYXQpKSB7CiAgICAgICAgY21zU2lnbmFsRXJyb3IoQ29udGV4dElELCBjbXNFUlJPUl9DT0xPUlNQQUNFX0NIRUNLLCAiV3Jvbmcgb3V0cHV0IGNvbG9yIHNwYWNlIG9uIHRyYW5zZm9ybSIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8vIENyZWF0ZSBhIHBpcGVsaW5lIHdpdGggYWxsIHRyYW5zZm9ybWF0aW9ucwogICAgTHV0ID0gX2Ntc0xpbmtQcm9maWxlcyhDb250ZXh0SUQsIG5Qcm9maWxlcywgSW50ZW50cywgaFByb2ZpbGVzLCBCUEMsIEFkYXB0YXRpb25TdGF0ZXMsIGR3RmxhZ3MpOwogICAgaWYgKEx1dCA9PSBOVUxMKSB7CiAgICAgICAgY21zU2lnbmFsRXJyb3IoQ29udGV4dElELCBjbXNFUlJPUl9OT1RfU1VJVEFCTEUsICJDb3VsZG4ndCBsaW5rIHRoZSBwcm9maWxlcyIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8vIENoZWNrIGNoYW5uZWwgY291bnQKICAgIGlmICgoY21zQ2hhbm5lbHNPZihFbnRyeUNvbG9yU3BhY2UpICE9IGNtc1BpcGVsaW5lSW5wdXRDaGFubmVscyhMdXQpKSB8fAogICAgICAgIChjbXNDaGFubmVsc09mKEV4aXRDb2xvclNwYWNlKSAgIT0gY21zUGlwZWxpbmVPdXRwdXRDaGFubmVscyhMdXQpKSkgewogICAgICAgIGNtc1BpcGVsaW5lRnJlZShMdXQpOwogICAgICAgIGNtc1NpZ25hbEVycm9yKENvbnRleHRJRCwgY21zRVJST1JfTk9UX1NVSVRBQkxFLCAiQ2hhbm5lbCBjb3VudCBkb2Vzbid0IG1hdGNoLiBQcm9maWxlIGlzIGNvcnJ1cHRlZCIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKCiAgICAvLyBBbGwgc2VlbXMgb2sKICAgIHhmb3JtID0gQWxsb2NFbXB0eVRyYW5zZm9ybShDb250ZXh0SUQsIEx1dCwgTGFzdEludGVudCwgJklucHV0Rm9ybWF0LCAmT3V0cHV0Rm9ybWF0LCAmZHdGbGFncyk7CiAgICBpZiAoeGZvcm0gPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8vIEtlZXAgdmFsdWVzCiAgICB4Zm9ybSAtPkVudHJ5Q29sb3JTcGFjZSA9IEVudHJ5Q29sb3JTcGFjZTsKICAgIHhmb3JtIC0+RXhpdENvbG9yU3BhY2UgID0gRXhpdENvbG9yU3BhY2U7CiAgICB4Zm9ybSAtPlJlbmRlcmluZ0ludGVudCA9IEludGVudHNbblByb2ZpbGVzLTFdOwoKICAgIC8vIFRha2Ugd2hpdGUgcG9pbnRzCiAgICBTZXRXaGl0ZVBvaW50KCZ4Zm9ybS0+RW50cnlXaGl0ZVBvaW50LCAoY21zQ0lFWFlaKikgY21zUmVhZFRhZyhoUHJvZmlsZXNbMF0sIGNtc1NpZ01lZGlhV2hpdGVQb2ludFRhZykpOwogICAgU2V0V2hpdGVQb2ludCgmeGZvcm0tPkV4aXRXaGl0ZVBvaW50LCAgKGNtc0NJRVhZWiopIGNtc1JlYWRUYWcoaFByb2ZpbGVzW25Qcm9maWxlcy0xXSwgY21zU2lnTWVkaWFXaGl0ZVBvaW50VGFnKSk7CgoKICAgIC8vIENyZWF0ZSBhIGdhbXV0IGNoZWNrIExVVCBpZiByZXF1ZXN0ZWQKICAgIGlmIChoR2FtdXRQcm9maWxlICE9IE5VTEwgJiYgKGR3RmxhZ3MgJiBjbXNGTEFHU19HQU1VVENIRUNLKSkKICAgICAgICB4Zm9ybSAtPkdhbXV0Q2hlY2sgID0gX2Ntc0NyZWF0ZUdhbXV0Q2hlY2tQaXBlbGluZShDb250ZXh0SUQsIGhQcm9maWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCUEMsIEludGVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWRhcHRhdGlvblN0YXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuR2FtdXRQQ1Nwb3NpdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoR2FtdXRQcm9maWxlKTsKCgogICAgLy8gVHJ5IHRvIHJlYWQgaW5wdXQgYW5kIG91dHB1dCBjb2xvcmFudCB0YWJsZQogICAgaWYgKGNtc0lzVGFnKGhQcm9maWxlc1swXSwgY21zU2lnQ29sb3JhbnRUYWJsZVRhZykpIHsKCiAgICAgICAgLy8gSW5wdXQgdGFibGUgY2FuIG9ubHkgY29tZSBpbiB0aGlzIHdheS4KICAgICAgICB4Zm9ybSAtPklucHV0Q29sb3JhbnQgPSBjbXNEdXBOYW1lZENvbG9yTGlzdCgoY21zTkFNRURDT0xPUkxJU1QqKSBjbXNSZWFkVGFnKGhQcm9maWxlc1swXSwgY21zU2lnQ29sb3JhbnRUYWJsZVRhZykpOwogICAgfQoKICAgIC8vIE91dHB1dCBpcyBhIGxpdHRsZSBiaXQgbW9yZSBjb21wbGV4LgogICAgaWYgKGNtc0dldERldmljZUNsYXNzKGhQcm9maWxlc1tuUHJvZmlsZXMtMV0pID09IGNtc1NpZ0xpbmtDbGFzcykgewoKICAgICAgICAvLyBUaGlzIHRhZyBtYXkgZXhpc3Qgb25seSBvbiBkZXZpY2VsaW5rIHByb2ZpbGVzLgogICAgICAgIGlmIChjbXNJc1RhZyhoUHJvZmlsZXNbblByb2ZpbGVzLTFdLCBjbXNTaWdDb2xvcmFudFRhYmxlT3V0VGFnKSkgewoKICAgICAgICAgICAgLy8gSXQgbWF5IGJlIE5VTEwgaWYgZXJyb3IKICAgICAgICAgICAgeGZvcm0gLT5PdXRwdXRDb2xvcmFudCA9IGNtc0R1cE5hbWVkQ29sb3JMaXN0KChjbXNOQU1FRENPTE9STElTVCopIGNtc1JlYWRUYWcoaFByb2ZpbGVzW25Qcm9maWxlcy0xXSwgY21zU2lnQ29sb3JhbnRUYWJsZU91dFRhZykpOwogICAgICAgIH0KCiAgICB9IGVsc2UgewoKICAgICAgICBpZiAoY21zSXNUYWcoaFByb2ZpbGVzW25Qcm9maWxlcy0xXSwgY21zU2lnQ29sb3JhbnRUYWJsZVRhZykpIHsKCiAgICAgICAgICAgIHhmb3JtIC0+IE91dHB1dENvbG9yYW50ID0gY21zRHVwTmFtZWRDb2xvckxpc3QoKGNtc05BTUVEQ09MT1JMSVNUKikgY21zUmVhZFRhZyhoUHJvZmlsZXNbblByb2ZpbGVzLTFdLCBjbXNTaWdDb2xvcmFudFRhYmxlVGFnKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8vIFN0b3JlIHRoZSBzZXF1ZW5jZSBvZiBwcm9maWxlcwogICAgaWYgKGR3RmxhZ3MgJiBjbXNGTEFHU19LRUVQX1NFUVVFTkNFKSB7CiAgICAgICAgeGZvcm0gLT5TZXF1ZW5jZSA9IF9jbXNDb21waWxlUHJvZmlsZVNlcXVlbmNlKENvbnRleHRJRCwgblByb2ZpbGVzLCBoUHJvZmlsZXMpOwogICAgfQogICAgZWxzZQogICAgICAgIHhmb3JtIC0+U2VxdWVuY2UgPSBOVUxMOwoKICAgIC8vIElmIHRoaXMgaXMgYSBjYWNoZWQgdHJhbnNmb3JtLCBpbml0IGZpcnN0IHZhbHVlLCB3aGljaCBpcyB6ZXJvICgxNiBiaXRzIG9ubHkpCiAgICBpZiAoIShkd0ZsYWdzICYgY21zRkxBR1NfTk9DQUNIRSkpIHsKCiAgICAgICAgbWVtc2V0KCZ4Zm9ybSAtPkNhY2hlLkNhY2hlSW4sIDAsIHNpemVvZih4Zm9ybSAtPkNhY2hlLkNhY2hlSW4pKTsKCiAgICAgICAgaWYgKHhmb3JtIC0+R2FtdXRDaGVjayAhPSBOVUxMKSB7CiAgICAgICAgICAgIFRyYW5zZm9ybU9uZVBpeGVsV2l0aEdhbXV0Q2hlY2soeGZvcm0sIHhmb3JtIC0+Q2FjaGUuQ2FjaGVJbiwgeGZvcm0tPkNhY2hlLkNhY2hlT3V0KTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CgogICAgICAgICAgICB4Zm9ybSAtPkx1dCAtPkV2YWwxNkZuKHhmb3JtIC0+Q2FjaGUuQ2FjaGVJbiwgeGZvcm0tPkNhY2hlLkNhY2hlT3V0LCB4Zm9ybSAtPiBMdXQtPkRhdGEpOwogICAgICAgIH0KCiAgICB9CgogICAgcmV0dXJuIChjbXNIVFJBTlNGT1JNKSB4Zm9ybTsKfQoKLy8gTXVsdGlwcm9maWxlIHRyYW5zZm9ybXM6IEdhbXV0IGNoZWNrIGlzIG5vdCBhdmFpbGFibGUgaGVyZSwgYXMgaXQgaXMgdW5jbGVhciBmcm9tIHdoaWNoIHByb2ZpbGUgdGhlIGdhbXV0IGNvbWVzLgpjbXNIVFJBTlNGT1JNIENNU0VYUE9SVCBjbXNDcmVhdGVNdWx0aXByb2ZpbGVUcmFuc2Zvcm1USFIoY21zQ29udGV4dCBDb250ZXh0SUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNIUFJPRklMRSBoUHJvZmlsZXNbXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBuUHJvZmlsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgSW5wdXRGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgT3V0cHV0Rm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIEludGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBkd0ZsYWdzKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgaTsKICAgIGNtc0Jvb2wgQlBDWzI1Nl07CiAgICBjbXNVSW50MzJOdW1iZXIgSW50ZW50c1syNTZdOwogICAgY21zRmxvYXQ2NE51bWJlciBBZGFwdGF0aW9uU3RhdGVzWzI1Nl07CgogICAgaWYgKG5Qcm9maWxlcyA8PSAwIHx8IG5Qcm9maWxlcyA+IDI1NSkgewogICAgICAgICBjbXNTaWduYWxFcnJvcihDb250ZXh0SUQsIGNtc0VSUk9SX1JBTkdFLCAiV3JvbmcgbnVtYmVyIG9mIHByb2ZpbGVzLiAxLi4yNTUgZXhwZWN0ZWQsICVkIGZvdW5kLiIsIG5Qcm9maWxlcyk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgZm9yIChpPTA7IGkgPCBuUHJvZmlsZXM7IGkrKykgewogICAgICAgIEJQQ1tpXSA9IGR3RmxhZ3MgJiBjbXNGTEFHU19CTEFDS1BPSU5UQ09NUEVOU0FUSU9OID8gVFJVRSA6IEZBTFNFOwogICAgICAgIEludGVudHNbaV0gPSBJbnRlbnQ7CiAgICAgICAgQWRhcHRhdGlvblN0YXRlc1tpXSA9IGNtc1NldEFkYXB0YXRpb25TdGF0ZVRIUihDb250ZXh0SUQsIC0xKTsKICAgIH0KCgogICAgcmV0dXJuIGNtc0NyZWF0ZUV4dGVuZGVkVHJhbnNmb3JtKENvbnRleHRJRCwgblByb2ZpbGVzLCBoUHJvZmlsZXMsIEJQQywgSW50ZW50cywgQWRhcHRhdGlvblN0YXRlcywgTlVMTCwgMCwgSW5wdXRGb3JtYXQsIE91dHB1dEZvcm1hdCwgZHdGbGFncyk7Cn0KCgoKY21zSFRSQU5TRk9STSBDTVNFWFBPUlQgY21zQ3JlYXRlTXVsdGlwcm9maWxlVHJhbnNmb3JtKGNtc0hQUk9GSUxFIGhQcm9maWxlc1tdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBuUHJvZmlsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIElucHV0Rm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBPdXRwdXRGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIEludGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgZHdGbGFncykKewoKICAgIGlmIChuUHJvZmlsZXMgPD0gMCB8fCBuUHJvZmlsZXMgPiAyNTUpIHsKICAgICAgICAgY21zU2lnbmFsRXJyb3IoTlVMTCwgY21zRVJST1JfUkFOR0UsICJXcm9uZyBudW1iZXIgb2YgcHJvZmlsZXMuIDEuLjI1NSBleHBlY3RlZCwgJWQgZm91bmQuIiwgblByb2ZpbGVzKTsKICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIGNtc0NyZWF0ZU11bHRpcHJvZmlsZVRyYW5zZm9ybVRIUihjbXNHZXRQcm9maWxlQ29udGV4dElEKGhQcm9maWxlc1swXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFByb2ZpbGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Qcm9maWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnB1dEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdXRwdXRGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3RmxhZ3MpOwp9CgpjbXNIVFJBTlNGT1JNIENNU0VYUE9SVCBjbXNDcmVhdGVUcmFuc2Zvcm1USFIoY21zQ29udGV4dCBDb250ZXh0SUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNIUFJPRklMRSBJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBJbnB1dEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0hQUk9GSUxFIE91dHB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBPdXRwdXRGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgSW50ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIGR3RmxhZ3MpCnsKCiAgICBjbXNIUFJPRklMRSBoQXJyYXlbMl07CgogICAgaEFycmF5WzBdID0gSW5wdXQ7CiAgICBoQXJyYXlbMV0gPSBPdXRwdXQ7CgogICAgcmV0dXJuIGNtc0NyZWF0ZU11bHRpcHJvZmlsZVRyYW5zZm9ybVRIUihDb250ZXh0SUQsIGhBcnJheSwgT3V0cHV0ID09IE5VTEwgPyAxIDogMiwgSW5wdXRGb3JtYXQsIE91dHB1dEZvcm1hdCwgSW50ZW50LCBkd0ZsYWdzKTsKfQoKQ01TQVBJIGNtc0hUUkFOU0ZPUk0gQ01TRVhQT1JUIGNtc0NyZWF0ZVRyYW5zZm9ybShjbXNIUFJPRklMRSBJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgSW5wdXRGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zSFBST0ZJTEUgT3V0cHV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBPdXRwdXRGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIEludGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgZHdGbGFncykKewogICAgcmV0dXJuIGNtc0NyZWF0ZVRyYW5zZm9ybVRIUihjbXNHZXRQcm9maWxlQ29udGV4dElEKElucHV0KSwgSW5wdXQsIElucHV0Rm9ybWF0LCBPdXRwdXQsIE91dHB1dEZvcm1hdCwgSW50ZW50LCBkd0ZsYWdzKTsKfQoKCmNtc0hUUkFOU0ZPUk0gQ01TRVhQT1JUIGNtc0NyZWF0ZVByb29maW5nVHJhbnNmb3JtVEhSKGNtc0NvbnRleHQgQ29udGV4dElELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNIUFJPRklMRSBJbnB1dFByb2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBJbnB1dEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zSFBST0ZJTEUgT3V0cHV0UHJvZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIE91dHB1dEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zSFBST0ZJTEUgUHJvb2ZpbmdQcm9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgbkludGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIFByb29maW5nSW50ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgZHdGbGFncykKewogICAgY21zSFBST0ZJTEUgaEFycmF5WzRdOwogICAgY21zVUludDMyTnVtYmVyIEludGVudHNbNF07CiAgICBjbXNCb29sICBCUENbNF07CiAgICBjbXNGbG9hdDY0TnVtYmVyIEFkYXB0YXRpb25bNF07CiAgICBjbXNCb29sICBEb0JQQyA9IChkd0ZsYWdzICYgY21zRkxBR1NfQkxBQ0tQT0lOVENPTVBFTlNBVElPTikgPyBUUlVFIDogRkFMU0U7CgoKICAgIGhBcnJheVswXSAgPSBJbnB1dFByb2ZpbGU7IGhBcnJheVsxXSA9IFByb29maW5nUHJvZmlsZTsgaEFycmF5WzJdICA9IFByb29maW5nUHJvZmlsZTsgICAgICAgICAgICAgICBoQXJyYXlbM10gPSBPdXRwdXRQcm9maWxlOwogICAgSW50ZW50c1swXSA9IG5JbnRlbnQ7ICAgICAgSW50ZW50c1sxXSA9IG5JbnRlbnQ7ICAgICAgICBJbnRlbnRzWzJdID0gSU5URU5UX1JFTEFUSVZFX0NPTE9SSU1FVFJJQzsgIEludGVudHNbM10gPSBQcm9vZmluZ0ludGVudDsKICAgIEJQQ1swXSAgICAgPSBEb0JQQzsgICAgICAgIEJQQ1sxXSA9IERvQlBDOyAgICAgICAgICAgICAgQlBDWzJdID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCUENbM10gPSAwOwoKICAgIEFkYXB0YXRpb25bMF0gPSBBZGFwdGF0aW9uWzFdID0gQWRhcHRhdGlvblsyXSA9IEFkYXB0YXRpb25bM10gPSBjbXNTZXRBZGFwdGF0aW9uU3RhdGVUSFIoQ29udGV4dElELCAtMSk7CgogICAgaWYgKCEoZHdGbGFncyAmIChjbXNGTEFHU19TT0ZUUFJPT0ZJTkd8Y21zRkxBR1NfR0FNVVRDSEVDSykpKQogICAgICAgIHJldHVybiBjbXNDcmVhdGVUcmFuc2Zvcm1USFIoQ29udGV4dElELCBJbnB1dFByb2ZpbGUsIElucHV0Rm9ybWF0LCBPdXRwdXRQcm9maWxlLCBPdXRwdXRGb3JtYXQsIG5JbnRlbnQsIGR3RmxhZ3MpOwoKICAgIHJldHVybiBjbXNDcmVhdGVFeHRlbmRlZFRyYW5zZm9ybShDb250ZXh0SUQsIDQsIGhBcnJheSwgQlBDLCBJbnRlbnRzLCBBZGFwdGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvb2ZpbmdQcm9maWxlLCAxLCBJbnB1dEZvcm1hdCwgT3V0cHV0Rm9ybWF0LCBkd0ZsYWdzKTsKCn0KCgpjbXNIVFJBTlNGT1JNIENNU0VYUE9SVCBjbXNDcmVhdGVQcm9vZmluZ1RyYW5zZm9ybShjbXNIUFJPRklMRSBJbnB1dFByb2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBJbnB1dEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zSFBST0ZJTEUgT3V0cHV0UHJvZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIE91dHB1dEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zSFBST0ZJTEUgUHJvb2ZpbmdQcm9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgbkludGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIFByb29maW5nSW50ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgZHdGbGFncykKewogICAgcmV0dXJuIGNtc0NyZWF0ZVByb29maW5nVHJhbnNmb3JtVEhSKGNtc0dldFByb2ZpbGVDb250ZXh0SUQoSW5wdXRQcm9maWxlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5wdXRQcm9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnB1dEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3V0cHV0UHJvZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3V0cHV0Rm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9vZmluZ1Byb2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5JbnRlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByb29maW5nSW50ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd0ZsYWdzKTsKfQoKCi8vIEdyYWIgdGhlIENvbnRleHRJRCBmcm9tIGFuIG9wZW4gdHJhbnNmb3JtLiBSZXR1cm5zIE5VTEwgaWYgYSBOVUxMIHRyYW5zZm9ybSBpcyBwYXNzZWQKY21zQ29udGV4dCBDTVNFWFBPUlQgY21zR2V0VHJhbnNmb3JtQ29udGV4dElEKGNtc0hUUkFOU0ZPUk0gaFRyYW5zZm9ybSkKewogICAgX2Ntc1RSQU5TRk9STSogeGZvcm0gPSAoX2Ntc1RSQU5TRk9STSopIGhUcmFuc2Zvcm07CgogICAgaWYgKHhmb3JtID09IE5VTEwpIHJldHVybiBOVUxMOwogICAgcmV0dXJuIHhmb3JtIC0+IENvbnRleHRJRDsKfQoKLy8gR3JhYiB0aGUgaW5wdXQvb3V0cHV0IGZvcm1hdHMKY21zVUludDMyTnVtYmVyIENNU0VYUE9SVCBjbXNHZXRUcmFuc2Zvcm1JbnB1dEZvcm1hdChjbXNIVFJBTlNGT1JNIGhUcmFuc2Zvcm0pCnsKICAgIF9jbXNUUkFOU0ZPUk0qIHhmb3JtID0gKF9jbXNUUkFOU0ZPUk0qKSBoVHJhbnNmb3JtOwoKICAgIGlmICh4Zm9ybSA9PSBOVUxMKSByZXR1cm4gMDsKICAgIHJldHVybiB4Zm9ybS0+SW5wdXRGb3JtYXQ7Cn0KCmNtc1VJbnQzMk51bWJlciBDTVNFWFBPUlQgY21zR2V0VHJhbnNmb3JtT3V0cHV0Rm9ybWF0KGNtc0hUUkFOU0ZPUk0gaFRyYW5zZm9ybSkKewogICAgX2Ntc1RSQU5TRk9STSogeGZvcm0gPSAoX2Ntc1RSQU5TRk9STSopIGhUcmFuc2Zvcm07CgogICAgaWYgKHhmb3JtID09IE5VTEwpIHJldHVybiAwOwogICAgcmV0dXJuIHhmb3JtLT5PdXRwdXRGb3JtYXQ7Cn0KCi8vIEZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eQpjbXNCb29sIENNU0VYUE9SVCBjbXNDaGFuZ2VCdWZmZXJzRm9ybWF0KGNtc0hUUkFOU0ZPUk0gaFRyYW5zZm9ybSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgSW5wdXRGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIE91dHB1dEZvcm1hdCkKewoKICAgIF9jbXNUUkFOU0ZPUk0qIHhmb3JtID0gKF9jbXNUUkFOU0ZPUk0qKSBoVHJhbnNmb3JtOwogICAgY21zRm9ybWF0dGVyMTYgRnJvbUlucHV0LCBUb091dHB1dDsKCgogICAgLy8gV2Ugb25seSBjYW4gYWZmb3JkIHRvIGNoYW5nZSBmb3JtYXR0ZXJzIGlmIHByZXZpb3VzIHRyYW5zZm9ybSBpcyBhdCBsZWFzdCAxNiBiaXRzCiAgICBpZiAoISh4Zm9ybSAtPmR3T3JpZ2luYWxGbGFncyAmIGNtc0ZMQUdTX0NBTl9DSEFOR0VfRk9STUFUVEVSKSkgewoKICAgICAgICBjbXNTaWduYWxFcnJvcih4Zm9ybSAtPkNvbnRleHRJRCwgY21zRVJST1JfTk9UX1NVSVRBQkxFLCAiY21zQ2hhbmdlQnVmZmVyc0Zvcm1hdCB3b3JrcyBvbmx5IG9uIHRyYW5zZm9ybXMgY3JlYXRlZCBvcmlnaW5hbGx5IHdpdGggYXQgbGVhc3QgMTYgYml0cyBvZiBwcmVjaXNpb24iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgRnJvbUlucHV0ID0gX2Ntc0dldEZvcm1hdHRlcih4Zm9ybS0+Q29udGV4dElELCBJbnB1dEZvcm1hdCwgIGNtc0Zvcm1hdHRlcklucHV0LCBDTVNfUEFDS19GTEFHU18xNkJJVFMpLkZtdDE2OwogICAgVG9PdXRwdXQgID0gX2Ntc0dldEZvcm1hdHRlcih4Zm9ybS0+Q29udGV4dElELCBPdXRwdXRGb3JtYXQsIGNtc0Zvcm1hdHRlck91dHB1dCwgQ01TX1BBQ0tfRkxBR1NfMTZCSVRTKS5GbXQxNjsKCiAgICBpZiAoRnJvbUlucHV0ID09IE5VTEwgfHwgVG9PdXRwdXQgPT0gTlVMTCkgewoKICAgICAgICBjbXNTaWduYWxFcnJvcih4Zm9ybSAtPiBDb250ZXh0SUQsIGNtc0VSUk9SX1VOS05PV05fRVhURU5TSU9OLCAiVW5zdXBwb3J0ZWQgcmFzdGVyIGZvcm1hdCIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICB4Zm9ybSAtPklucHV0Rm9ybWF0ICA9IElucHV0Rm9ybWF0OwogICAgeGZvcm0gLT5PdXRwdXRGb3JtYXQgPSBPdXRwdXRGb3JtYXQ7CiAgICB4Zm9ybSAtPkZyb21JbnB1dCAgICA9IEZyb21JbnB1dDsKICAgIHhmb3JtIC0+VG9PdXRwdXQgICAgID0gVG9PdXRwdXQ7CiAgICByZXR1cm4gVFJVRTsKfQo=