Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8KLy8gIExpdHRsZSBDb2xvciBNYW5hZ2VtZW50IFN5c3RlbQovLyAgQ29weXJpZ2h0IChjKSAxOTk4LTIwMTQgTWFydGkgTWFyaWEgU2FndWVyCi8vCi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwovLyBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksCi8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24KLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCi8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZQovLyBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgovLwovLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgovLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KLy8KLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCi8vIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTwovLyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORAovLyBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFCi8vIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04KLy8gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OCi8vIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLwoKI2luY2x1ZGUgImxjbXMyX2ludGVybmFsLmgiCgovLyBUYWcgU2VyaWFsaXphdGlvbiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gVGhpcyBmaWxlIGltcGxlbWVudHMgZXZlcnkgc2luZ2xlIHRhZyBhbmQgdGFnIHR5cGUgYXMgZGVzY3JpYmVkIGluIHRoZSBJQ0Mgc3BlYy4gU29tZSB0eXBlcwovLyBoYXZlIGJlZW4gZGVwcmVjYXRlZCwgbGlrZSBuY2wgYW5kIERhdGEuIFRoZXJlIGlzIG5vIGltcGxlbWVudGF0aW9uIGZvciB0aG9zZSB0eXBlcyBhcyB0aGVyZQovLyBhcmUgbm8gcHJvZmlsZXMgaG9sZGluZyB0aGVtLiBUaGUgcHJvZ3JhbW1lciBjYW4gYWxzbyBleHRlbmQgdGhpcyBsaXN0IGJ5IGRlZmluaW5nIGhpcyBvd24gdHlwZXMKLy8gYnkgdXNpbmcgdGhlIGFwcHJvcGlhdGUgcGx1Zy1pbi4gVGhlcmUgYXJlIHRocmVlIHR5cGVzIG9mIHBsdWcgaW5zIHJlZ2FyZGluZyB0aGF0LiBGaXJzdCB0eXBlCi8vIGFsbG93cyB0byBkZWZpbmUgbmV3IHRhZ3MgdXNpbmcgYW55IGV4aXN0aW5nIHR5cGUuIE5leHQgcGx1Zy1pbiB0eXBlIGFsbG93cyB0byBkZWZpbmUgbmV3IHR5cGVzCi8vIGFuZCB0aGUgdGhpcmQgb25lIGlzIHZlcnkgc3BlY2lmaWM6IGFsbG93cyB0byBleHRlbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbXVsdGlwcm9jZXNzaW5nCi8vIGVsZW1lbnRzIHNwZWNpYWwgdHlwZS4KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLy8gU29tZSBicm9rZW4gdHlwZXMKI2RlZmluZSBjbXNDb3JiaXNCcm9rZW5YWVp0eXBlICAgICgoY21zVGFnVHlwZVNpZ25hdHVyZSkgMHgxN0E1MDVCOCkKI2RlZmluZSBjbXNNb25hY29Ccm9rZW5DdXJ2ZVR5cGUgICgoY21zVGFnVHlwZVNpZ25hdHVyZSkgMHg5NDc4ZWUwMCkKCi8vIFRoaXMgaXMgdGhlIGxpbmtlZCBsaXN0IHRoYXQga2VlcHMgdHJhY2sgb2YgdGhlIGRlZmluZWQgdHlwZXMKdHlwZWRlZiBzdHJ1Y3QgX2Ntc1RhZ1R5cGVMaW5rZWRMaXN0X3N0IHsKCiAgICBjbXNUYWdUeXBlSGFuZGxlciBIYW5kbGVyOwogICAgc3RydWN0IF9jbXNUYWdUeXBlTGlua2VkTGlzdF9zdCogTmV4dDsKCn0gX2Ntc1RhZ1R5cGVMaW5rZWRMaXN0OwoKLy8gU29tZSBtYWNyb3MgdG8gZGVmaW5lIGNhbGxiYWNrcy4KI2RlZmluZSBSRUFEX0ZOKHgpICBUeXBlXyMjeCMjX1JlYWQKI2RlZmluZSBXUklURV9GTih4KSBUeXBlXyMjeCMjX1dyaXRlCiNkZWZpbmUgRlJFRV9GTih4KSAgVHlwZV8jI3gjI19GcmVlCiNkZWZpbmUgRFVQX0ZOKHgpICAgVHlwZV8jI3gjI19EdXAKCi8vIEhlbHBlciBtYWNybyB0byBkZWZpbmUgYSBoYW5kbGVyLiBDYWxsYmFja3MgZG8gaGF2ZSBhIGZpeGVkIG5hbWluZyBjb252ZW50aW9uLgojZGVmaW5lIFRZUEVfSEFORExFUih0LCB4KSAgeyAodCksIFJFQURfRk4oeCksIFdSSVRFX0ZOKHgpLCBEVVBfRk4oeCksIEZSRUVfRk4oeCksIE5VTEwsIDAgfQoKLy8gSGVscGVyIG1hY3JvIHRvIGRlZmluZSBhIE1QRSBoYW5kbGVyLiBDYWxsYmFja3MgZG8gaGF2ZSBhIGZpeGVkIG5hbWluZyBjb252ZW50aW9uCiNkZWZpbmUgVFlQRV9NUEVfSEFORExFUih0LCB4KSAgeyAodCksIFJFQURfRk4oeCksIFdSSVRFX0ZOKHgpLCBHZW5lcmljTVBFZHVwLCBHZW5lcmljTVBFZnJlZSwgTlVMTCwgMCB9CgovLyBSZWdpc3RlciBhIG5ldyB0eXBlIGhhbmRsZXIuIFRoaXMgcm91dGluZSBpcyBzaGFyZWQgYmV0d2VlbiBub3JtYWwgdHlwZXMgYW5kIE1QRS4gTGlua2VkTGlzdCBwb2ludHMgdG8gdGhlIG9wdGlvbmFsIGxpc3QgaGVhZApzdGF0aWMKY21zQm9vbCBSZWdpc3RlclR5cGVzUGx1Z2luKGNtc0NvbnRleHQgaWQsIGNtc1BsdWdpbkJhc2UqIERhdGEsIF9jbXNNZW1vcnlDbGllbnQgcG9zKQp7CiAgICBjbXNQbHVnaW5UYWdUeXBlKiBQbHVnaW4gPSAoY21zUGx1Z2luVGFnVHlwZSopIERhdGE7CiAgICBfY21zVGFnVHlwZVBsdWdpbkNodW5rVHlwZSogY3R4ID0gKCBfY21zVGFnVHlwZVBsdWdpbkNodW5rVHlwZSopIF9jbXNDb250ZXh0R2V0Q2xpZW50Q2h1bmsoaWQsIHBvcyk7CiAgICBfY21zVGFnVHlwZUxpbmtlZExpc3QgKnB0OwoKICAgIC8vIENhbGxpbmcgdGhlIGZ1bmN0aW9uIHdpdGggTlVMTCBhcyBwbHVnLWluIHdvdWxkIHVucmVnaXN0ZXIgdGhlIHBsdWcgaW4uCiAgICBpZiAoRGF0YSA9PSBOVUxMKSB7CgogICAgICAgIC8vIFRoZXJlIGlzIG5vIG5lZWQgdG8gc2V0IGZyZWUgdGhlIG1lbW9yeSwgYXMgcG9vbCBpcyBkZXN0cm95ZWQgYXMgYSB3aG9sZS4KICAgICAgICBjdHggLT5UYWdUeXBlcyA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgLy8gUmVnaXN0ZXJpbmcgaGFwcGVucyBpbiBwbHVnLWluIG1lbW9yeSBwb29sLgogICAgcHQgPSAoX2Ntc1RhZ1R5cGVMaW5rZWRMaXN0KikgX2Ntc1BsdWdpbk1hbGxvYyhpZCwgc2l6ZW9mKF9jbXNUYWdUeXBlTGlua2VkTGlzdCkpOwogICAgaWYgKHB0ID09IE5VTEwpIHJldHVybiBGQUxTRTsKCiAgICBwdCAtPkhhbmRsZXIgICA9IFBsdWdpbiAtPkhhbmRsZXI7CiAgICBwdCAtPk5leHQgICAgICA9IGN0eCAtPlRhZ1R5cGVzOwoKICAgIGN0eCAtPlRhZ1R5cGVzID0gcHQ7CiAgICAgCiAgICByZXR1cm4gVFJVRTsKfQoKLy8gUmV0dXJuIGhhbmRsZXIgZm9yIGEgZ2l2ZW4gdHlwZSBvciBOVUxMIGlmIG5vdCBmb3VuZC4gU2hhcmVkIGJldHdlZW4gbm9ybWFsIHR5cGVzIGFuZCBNUEUuIEl0IGZpcnN0IHRyaWVzIHRoZSBhZGRpdG9ucyAKLy8gbWFkZSBieSBwbHVnLWlucyBhbmQgdGhlbiB0aGUgYnVpbHQtaW4gZGVmYXVsdHMuCnN0YXRpYwpjbXNUYWdUeXBlSGFuZGxlciogR2V0SGFuZGxlcihjbXNUYWdUeXBlU2lnbmF0dXJlIHNpZywgX2Ntc1RhZ1R5cGVMaW5rZWRMaXN0KiBQbHVnaW5MaW5rZWRMaXN0LCBfY21zVGFnVHlwZUxpbmtlZExpc3QqIERlZmF1bHRMaW5rZWRMaXN0KQp7CiAgICBfY21zVGFnVHlwZUxpbmtlZExpc3QqIHB0OwoKICAgIGZvciAocHQgPSBQbHVnaW5MaW5rZWRMaXN0OwogICAgICAgICBwdCAhPSBOVUxMOwogICAgICAgICBwdCA9IHB0IC0+TmV4dCkgewoKICAgICAgICAgICAgaWYgKHNpZyA9PSBwdCAtPiBIYW5kbGVyLlNpZ25hdHVyZSkgcmV0dXJuICZwdCAtPkhhbmRsZXI7CiAgICB9CgogICAgZm9yIChwdCA9IERlZmF1bHRMaW5rZWRMaXN0OwogICAgICAgICBwdCAhPSBOVUxMOwogICAgICAgICBwdCA9IHB0IC0+TmV4dCkgewoKICAgICAgICAgICAgaWYgKHNpZyA9PSBwdCAtPiBIYW5kbGVyLlNpZ25hdHVyZSkgcmV0dXJuICZwdCAtPkhhbmRsZXI7CiAgICB9CgogICAgcmV0dXJuIE5VTEw7Cn0KCgovLyBBdXhpbGlhciB0byBjb252ZXJ0IFVURi0zMiB0byBVVEYtMTYgaW4gc29tZSBjYXNlcwpzdGF0aWMKY21zQm9vbCBfY21zV3JpdGVXQ2hhckFycmF5KGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciBuLCBjb25zdCB3Y2hhcl90KiBBcnJheSkKewogICAgY21zVUludDMyTnVtYmVyIGk7CgogICAgX2Ntc0Fzc2VydChpbyAhPSBOVUxMKTsKICAgIF9jbXNBc3NlcnQoIShBcnJheSA9PSBOVUxMICYmIG4gPiAwKSk7CgogICAgZm9yIChpPTA7IGkgPCBuOyBpKyspIHsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgKGNtc1VJbnQxNk51bWJlcikgQXJyYXlbaV0pKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8vIEF1eGlsaWFyIHRvIHJlYWQgYW4gYXJyYXkgb2Ygd2NoYXJfdApzdGF0aWMKY21zQm9vbCBfY21zUmVhZFdDaGFyQXJyYXkoY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyIG4sIHdjaGFyX3QqIEFycmF5KQp7CiAgICBjbXNVSW50MzJOdW1iZXIgaTsKICAgIGNtc1VJbnQxNk51bWJlciB0bXA7CgogICAgX2Ntc0Fzc2VydChpbyAhPSBOVUxMKTsKCiAgICBmb3IgKGk9MDsgaSA8IG47IGkrKykgewoKICAgICAgICBpZiAoQXJyYXkgIT0gTlVMTCkgewoKICAgICAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJnRtcCkpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgQXJyYXlbaV0gPSAod2NoYXJfdCkgdG1wOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgTlVMTCkpIHJldHVybiBGQUxTRTsKICAgICAgICB9CgogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCi8vIFRvIGRlYWwgd2l0aCBwb3NpdGlvbiB0YWJsZXMKdHlwZWRlZiBjbXNCb29sICgqIFBvc2l0aW9uVGFibGVFbnRyeUZuKShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0lPSEFORExFUiogaW8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIENhcmdvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZyk7CgovLyBIZWxwZXIgZnVuY3Rpb24gdG8gZGVhbCB3aXRoIHBvc2l0aW9uIHRhYmxlcyBhcyBkZWNyaWJlZCBpbiBJQ0Mgc3BlYyA0LjMKLy8gQSB0YWJsZSBvZiBuIGVsZW1lbnRzIGlzIHJlYWRlZCwgd2hlcmUgZmlyc3QgY29tZXMgbiByZWNvcmRzIGNvbnRhaW5pbmcgb2Zmc2V0cyBhbmQgc2l6ZXMgYW5kCi8vIHRoZW4gYSBibG9jayBjb250YWluaW5nIHRoZSBkYXRhIGl0c2VsZi4gVGhpcyBhbGxvd3MgdG8gcmV1c2Ugc2FtZSBkYXRhIGluIG1vcmUgdGhhbiBvbmUgZW50cnkKc3RhdGljCmNtc0Jvb2wgUmVhZFBvc2l0aW9uVGFibGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNJT0hBTkRMRVIqIGlvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBCYXNlT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpDYXJnbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9zaXRpb25UYWJsZUVudHJ5Rm4gRWxlbWVudEZuKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgaTsKICAgIGNtc1VJbnQzMk51bWJlciAqRWxlbWVudE9mZnNldHMgPSBOVUxMLCAqRWxlbWVudFNpemVzID0gTlVMTDsKCiAgICAvLyBMZXQncyB0YWtlIHRoZSBvZmZzZXRzIHRvIGVhY2ggZWxlbWVudAogICAgRWxlbWVudE9mZnNldHMgPSAoY21zVUludDMyTnVtYmVyICopIF9jbXNDYWxsb2MoaW8gLT5Db250ZXh0SUQsIENvdW50LCBzaXplb2YoY21zVUludDMyTnVtYmVyKSk7CiAgICBpZiAoRWxlbWVudE9mZnNldHMgPT0gTlVMTCkgZ290byBFcnJvcjsKCiAgICBFbGVtZW50U2l6ZXMgPSAoY21zVUludDMyTnVtYmVyICopIF9jbXNDYWxsb2MoaW8gLT5Db250ZXh0SUQsIENvdW50LCBzaXplb2YoY21zVUludDMyTnVtYmVyKSk7CiAgICBpZiAoRWxlbWVudFNpemVzID09IE5VTEwpIGdvdG8gRXJyb3I7CgogICAgZm9yIChpPTA7IGkgPCBDb3VudDsgaSsrKSB7CgogICAgICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZFbGVtZW50T2Zmc2V0c1tpXSkpIGdvdG8gRXJyb3I7CiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJkVsZW1lbnRTaXplc1tpXSkpIGdvdG8gRXJyb3I7CgogICAgICAgIEVsZW1lbnRPZmZzZXRzW2ldICs9IEJhc2VPZmZzZXQ7CiAgICB9CgogICAgLy8gU2VlayB0byBlYWNoIGVsZW1lbnQgYW5kIHJlYWQgaXQKICAgIGZvciAoaT0wOyBpIDwgQ291bnQ7IGkrKykgewoKICAgICAgICBpZiAoIWlvIC0+IFNlZWsoaW8sIEVsZW1lbnRPZmZzZXRzW2ldKSkgZ290byBFcnJvcjsKCiAgICAgICAgLy8gVGhpcyBpcyB0aGUgcmVhZGVyIGNhbGxiYWNrCiAgICAgICAgaWYgKCFFbGVtZW50Rm4oc2VsZiwgaW8sIENhcmdvLCBpLCBFbGVtZW50U2l6ZXNbaV0pKSBnb3RvIEVycm9yOwogICAgfQoKICAgIC8vIFN1Y2Nlc3MKICAgIGlmIChFbGVtZW50T2Zmc2V0cyAhPSBOVUxMKSBfY21zRnJlZShpbyAtPkNvbnRleHRJRCwgRWxlbWVudE9mZnNldHMpOwogICAgaWYgKEVsZW1lbnRTaXplcyAhPSBOVUxMKSBfY21zRnJlZShpbyAtPkNvbnRleHRJRCwgRWxlbWVudFNpemVzKTsKICAgIHJldHVybiBUUlVFOwoKRXJyb3I6CiAgICBpZiAoRWxlbWVudE9mZnNldHMgIT0gTlVMTCkgX2Ntc0ZyZWUoaW8gLT5Db250ZXh0SUQsIEVsZW1lbnRPZmZzZXRzKTsKICAgIGlmIChFbGVtZW50U2l6ZXMgIT0gTlVMTCkgX2Ntc0ZyZWUoaW8gLT5Db250ZXh0SUQsIEVsZW1lbnRTaXplcyk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8vIFNhbWUgYXMgYW50ZXJpb3IsIGJ1dCBmb3Igd3JpdGUgcG9zaXRpb24gdGFibGVzCnN0YXRpYwpjbXNCb29sIFdyaXRlUG9zaXRpb25UYWJsZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNJT0hBTkRMRVIqIGlvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBCYXNlT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQ2FyZ28sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3NpdGlvblRhYmxlRW50cnlGbiBFbGVtZW50Rm4pCnsKICAgIGNtc1VJbnQzMk51bWJlciBpOwogICAgY21zVUludDMyTnVtYmVyIERpcmVjdG9yeVBvcywgQ3VycmVudFBvcywgQmVmb3JlOwogICAgY21zVUludDMyTnVtYmVyICpFbGVtZW50T2Zmc2V0cyA9IE5VTEwsICpFbGVtZW50U2l6ZXMgPSBOVUxMOwoKICAgICAvLyBDcmVhdGUgdGFibGUKICAgIEVsZW1lbnRPZmZzZXRzID0gKGNtc1VJbnQzMk51bWJlciAqKSBfY21zQ2FsbG9jKGlvIC0+Q29udGV4dElELCBDb3VudCwgc2l6ZW9mKGNtc1VJbnQzMk51bWJlcikpOwogICAgaWYgKEVsZW1lbnRPZmZzZXRzID09IE5VTEwpIGdvdG8gRXJyb3I7CgogICAgRWxlbWVudFNpemVzID0gKGNtc1VJbnQzMk51bWJlciAqKSBfY21zQ2FsbG9jKGlvIC0+Q29udGV4dElELCBDb3VudCwgc2l6ZW9mKGNtc1VJbnQzMk51bWJlcikpOwogICAgaWYgKEVsZW1lbnRTaXplcyA9PSBOVUxMKSBnb3RvIEVycm9yOwoKICAgIC8vIEtlZXAgc3RhcnRpbmcgcG9zaXRpb24gb2YgY3VydmUgb2Zmc2V0cwogICAgRGlyZWN0b3J5UG9zID0gaW8gLT5UZWxsKGlvKTsKCiAgICAvLyBXcml0ZSBhIGZha2UgZGlyZWN0b3J5IHRvIGJlIGZpbGxlZCBsYXR0ZXIgb24KICAgIGZvciAoaT0wOyBpIDwgQ291bnQ7IGkrKykgewoKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgMCkpIGdvdG8gRXJyb3I7ICAvLyBPZmZzZXQKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgMCkpIGdvdG8gRXJyb3I7ICAvLyBzaXplCiAgICB9CgogICAgLy8gV3JpdGUgZWFjaCBlbGVtZW50LiBLZWVwIHRyYWNrIG9mIHRoZSBzaXplIGFzIHdlbGwuCiAgICBmb3IgKGk9MDsgaSA8IENvdW50OyBpKyspIHsKCiAgICAgICAgQmVmb3JlID0gaW8gLT5UZWxsKGlvKTsKICAgICAgICBFbGVtZW50T2Zmc2V0c1tpXSA9IEJlZm9yZSAtIEJhc2VPZmZzZXQ7CgogICAgICAgIC8vIENhbGxiYWNrIHRvIHdyaXRlLi4uCiAgICAgICAgaWYgKCFFbGVtZW50Rm4oc2VsZiwgaW8sIENhcmdvLCBpLCBTaXplT2ZUYWcpKSBnb3RvIEVycm9yOwoKICAgICAgICAvLyBOb3cgdGhlIHNpemUKICAgICAgICBFbGVtZW50U2l6ZXNbaV0gPSBpbyAtPlRlbGwoaW8pIC0gQmVmb3JlOwogICAgfQoKICAgIC8vIFdyaXRlIHRoZSBkaXJlY3RvcnkKICAgIEN1cnJlbnRQb3MgPSBpbyAtPlRlbGwoaW8pOwogICAgaWYgKCFpbyAtPlNlZWsoaW8sIERpcmVjdG9yeVBvcykpIGdvdG8gRXJyb3I7CgogICAgZm9yIChpPTA7IGkgPCAgQ291bnQ7IGkrKykgewogICAgICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBFbGVtZW50T2Zmc2V0c1tpXSkpIGdvdG8gRXJyb3I7CiAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIEVsZW1lbnRTaXplc1tpXSkpIGdvdG8gRXJyb3I7CiAgICB9CgogICAgaWYgKCFpbyAtPlNlZWsoaW8sIEN1cnJlbnRQb3MpKSBnb3RvIEVycm9yOwoKICAgIGlmIChFbGVtZW50T2Zmc2V0cyAhPSBOVUxMKSBfY21zRnJlZShpbyAtPkNvbnRleHRJRCwgRWxlbWVudE9mZnNldHMpOwogICAgaWYgKEVsZW1lbnRTaXplcyAhPSBOVUxMKSBfY21zRnJlZShpbyAtPkNvbnRleHRJRCwgRWxlbWVudFNpemVzKTsKICAgIHJldHVybiBUUlVFOwoKRXJyb3I6CiAgICBpZiAoRWxlbWVudE9mZnNldHMgIT0gTlVMTCkgX2Ntc0ZyZWUoaW8gLT5Db250ZXh0SUQsIEVsZW1lbnRPZmZzZXRzKTsKICAgIGlmIChFbGVtZW50U2l6ZXMgIT0gTlVMTCkgX2Ntc0ZyZWUoaW8gLT5Db250ZXh0SUQsIEVsZW1lbnRTaXplcyk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUeXBlIFhZWi4gT25seSBvbmUgdmFsdWUgaXMgYWxsb3dlZAovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKLy9UaGUgWFlaVHlwZSBjb250YWlucyBhbiBhcnJheSBvZiB0aHJlZSBlbmNvZGVkIHZhbHVlcyBmb3IgdGhlIFhZWiB0cmlzdGltdWx1cwovL3ZhbHVlcy4gVHJpc3RpbXVsdXMgdmFsdWVzIG11c3QgYmUgbm9uLW5lZ2F0aXZlLiBUaGUgc2lnbmVkIGVuY29kaW5nIGFsbG93cyBmb3IKLy9pbXBsZW1lbnRhdGlvbiBvcHRpbWl6YXRpb25zIGJ5IG1pbmltaXppbmcgdGhlIG51bWJlciBvZiBmaXhlZCBmb3JtYXRzLgoKCnN0YXRpYwp2b2lkICpUeXBlX1hZWl9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc0NJRVhZWiogeHl6OwoKICAgICpuSXRlbXMgPSAwOwogICAgeHl6ID0gKGNtc0NJRVhZWiopIF9jbXNNYWxsb2NaZXJvKHNlbGYgLT5Db250ZXh0SUQsIHNpemVvZihjbXNDSUVYWVopKTsKICAgIGlmICh4eXogPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgaWYgKCFfY21zUmVhZFhZWk51bWJlcihpbywgeHl6KSkgewogICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIHh5eik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgKm5JdGVtcyA9IDE7CiAgICByZXR1cm4gKHZvaWQqKSB4eXo7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwp9CgpzdGF0aWMKY21zQm9vbCAgVHlwZV9YWVpfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIHJldHVybiBfY21zV3JpdGVYWVpOdW1iZXIoaW8sIChjbXNDSUVYWVoqKSBQdHIpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCnN0YXRpYwp2b2lkKiBUeXBlX1hZWl9EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkICpQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICByZXR1cm4gX2Ntc0R1cE1lbShzZWxmIC0+Q29udGV4dElELCBQdHIsIHNpemVvZihjbXNDSUVYWVopKTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG4pOwp9CgpzdGF0aWMKdm9pZCBUeXBlX1hZWl9GcmVlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgdm9pZCAqUHRyKQp7CiAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBQdHIpOwp9CgoKc3RhdGljCmNtc1RhZ1R5cGVTaWduYXR1cmUgRGVjaWRlWFladHlwZShjbXNGbG9hdDY0TnVtYmVyIElDQ1ZlcnNpb24sIGNvbnN0IHZvaWQgKkRhdGEpCnsKICAgIHJldHVybiBjbXNTaWdYWVpUeXBlOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoSUNDVmVyc2lvbik7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKERhdGEpOwp9CgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBjaHJvbWF0aWNpdHkuIE9ubHkgb25lIHZhbHVlIGlzIGFsbG93ZWQKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVGhlIGNocm9tYXRpY2l0eSB0YWcgdHlwZSBwcm92aWRlcyBiYXNpYyBjaHJvbWF0aWNpdHkgZGF0YSBhbmQgdHlwZSBvZgovLyBwaG9zcGhvcnMgb3IgY29sb3JhbnRzIG9mIGEgbW9uaXRvciB0byBhcHBsaWNhdGlvbnMgYW5kIHV0aWxpdGllcy4KCnN0YXRpYwp2b2lkICpUeXBlX0Nocm9tYXRpY2l0eV9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc0NJRXh5WVRSSVBMRSogY2hybTsKICAgIGNtc1VJbnQxNk51bWJlciBuQ2hhbnMsIFRhYmxlOwoKICAgICpuSXRlbXMgPSAwOwogICAgY2hybSA9ICAoY21zQ0lFeHlZVFJJUExFKikgX2Ntc01hbGxvY1plcm8oc2VsZiAtPkNvbnRleHRJRCwgc2l6ZW9mKGNtc0NJRXh5WVRSSVBMRSkpOwogICAgaWYgKGNocm0gPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJm5DaGFucykpIGdvdG8gRXJyb3I7CgogICAgLy8gTGV0J3MgcmVjb3ZlciBmcm9tIGEgYnVnIGludHJvZHVjZWQgaW4gZWFybHkgdmVyc2lvbnMgb2YgbGNtczEKICAgIGlmIChuQ2hhbnMgPT0gMCAmJiBTaXplT2ZUYWcgPT0gMzIpIHsKCiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgTlVMTCkpIGdvdG8gRXJyb3I7CiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJm5DaGFucykpIGdvdG8gRXJyb3I7CiAgICB9CgogICAgaWYgKG5DaGFucyAhPSAzKSBnb3RvIEVycm9yOwoKICAgIGlmICghX2Ntc1JlYWRVSW50MTZOdW1iZXIoaW8sICZUYWJsZSkpIGdvdG8gRXJyb3I7CgogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJmNocm0gLT5SZWQueCkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAmY2hybSAtPlJlZC55KSkgZ290byBFcnJvcjsKCiAgICBjaHJtIC0+UmVkLlkgPSAxLjA7CgogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJmNocm0gLT5HcmVlbi54KSkgZ290byBFcnJvcjsKICAgIGlmICghX2Ntc1JlYWQxNUZpeGVkMTZOdW1iZXIoaW8sICZjaHJtIC0+R3JlZW4ueSkpIGdvdG8gRXJyb3I7CgogICAgY2hybSAtPkdyZWVuLlkgPSAxLjA7CgogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJmNocm0gLT5CbHVlLngpKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJmNocm0gLT5CbHVlLnkpKSBnb3RvIEVycm9yOwoKICAgIGNocm0gLT5CbHVlLlkgPSAxLjA7CgogICAgKm5JdGVtcyA9IDE7CiAgICByZXR1cm4gKHZvaWQqKSBjaHJtOwoKRXJyb3I6CiAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCAodm9pZCopIGNocm0pOwogICAgcmV0dXJuIE5VTEw7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwp9CgpzdGF0aWMKY21zQm9vbCAgU2F2ZU9uZUNocm9tYXRpY2l0eShjbXNGbG9hdDY0TnVtYmVyIHgsIGNtc0Zsb2F0NjROdW1iZXIgeSwgY21zSU9IQU5ETEVSKiBpbykKewogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIF9jbXNEb3VibGVUbzE1Rml4ZWQxNih4KSkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBfY21zRG91YmxlVG8xNUZpeGVkMTYoeSkpKSByZXR1cm4gRkFMU0U7CgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYwpjbXNCb29sICBUeXBlX0Nocm9tYXRpY2l0eV9Xcml0ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIHZvaWQqIFB0ciwgY21zVUludDMyTnVtYmVyIG5JdGVtcykKewogICAgY21zQ0lFeHlZVFJJUExFKiBjaHJtID0gKGNtc0NJRXh5WVRSSVBMRSopIFB0cjsKCiAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgMykpIHJldHVybiBGQUxTRTsgICAgICAgIC8vIG5DaGFubmVscwogICAgaWYgKCFfY21zV3JpdGVVSW50MTZOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7ICAgICAgICAvLyBUYWJsZQoKICAgIGlmICghU2F2ZU9uZUNocm9tYXRpY2l0eShjaHJtIC0+IFJlZC54LCAgIGNocm0gLT4gUmVkLnksIGlvKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFTYXZlT25lQ2hyb21hdGljaXR5KGNocm0gLT4gR3JlZW4ueCwgY2hybSAtPiBHcmVlbi55LCBpbykpIHJldHVybiBGQUxTRTsKICAgIGlmICghU2F2ZU9uZUNocm9tYXRpY2l0eShjaHJtIC0+IEJsdWUueCwgIGNocm0gLT4gQmx1ZS55LCBpbykpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgpzdGF0aWMKdm9pZCogVHlwZV9DaHJvbWF0aWNpdHlfRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCAqUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICAgcmV0dXJuIF9jbXNEdXBNZW0oc2VsZiAtPkNvbnRleHRJRCwgUHRyLCBzaXplb2YoY21zQ0lFeHlZVFJJUExFKSk7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuKTsKfQoKc3RhdGljCnZvaWQgVHlwZV9DaHJvbWF0aWNpdHlfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQqIFB0cikKewogICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgUHRyKTsKfQoKCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFR5cGUgY21zU2lnQ29sb3JhbnRPcmRlclR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCi8vIFRoaXMgaXMgYW4gb3B0aW9uYWwgdGFnIHdoaWNoIHNwZWNpZmllcyB0aGUgbGF5ZG93biBvcmRlciBpbiB3aGljaCBjb2xvcmFudHMgd2lsbAovLyBiZSBwcmludGVkIG9uIGFuIG4tY29sb3JhbnQgZGV2aWNlLiBUaGUgbGF5ZG93biBvcmRlciBtYXkgYmUgdGhlIHNhbWUgYXMgdGhlCi8vIGNoYW5uZWwgZ2VuZXJhdGlvbiBvcmRlciBsaXN0ZWQgaW4gdGhlIGNvbG9yYW50VGFibGVUYWcgb3IgdGhlIGNoYW5uZWwgb3JkZXIgb2YgYQovLyBjb2xvdXIgc3BhY2Ugc3VjaCBhcyBDTVlLLCBpbiB3aGljaCBjYXNlIHRoaXMgdGFnIGlzIG5vdCBuZWVkZWQuIFdoZW4gdGhpcyBpcyBub3QKLy8gdGhlIGNhc2UgKGZvciBleGFtcGxlLCBpbmstdG93ZXJzIHNvbWV0aW1lcyB1c2UgdGhlIG9yZGVyIEtDTVkpLCB0aGlzIHRhZyBtYXkgYmUKLy8gdXNlZCB0byBzcGVjaWZ5IHRoZSBsYXlkb3duIG9yZGVyIG9mIHRoZSBjb2xvcmFudHMuCgoKc3RhdGljCnZvaWQgKlR5cGVfQ29sb3JhbnRPcmRlclR5cGVfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNVSW50OE51bWJlciogQ29sb3JhbnRPcmRlcjsKICAgIGNtc1VJbnQzMk51bWJlciBDb3VudDsKCiAgICAqbkl0ZW1zID0gMDsKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZDb3VudCkpIHJldHVybiBOVUxMOwogICAgaWYgKENvdW50ID4gY21zTUFYQ0hBTk5FTFMpIHJldHVybiBOVUxMOwoKICAgIENvbG9yYW50T3JkZXIgPSAoY21zVUludDhOdW1iZXIqKSBfY21zQ2FsbG9jKHNlbGYgLT5Db250ZXh0SUQsIGNtc01BWENIQU5ORUxTLCBzaXplb2YoY21zVUludDhOdW1iZXIpKTsKICAgIGlmIChDb2xvcmFudE9yZGVyID09IE5VTEwpIHJldHVybiBOVUxMOwoKICAgIC8vIFdlIHVzZSBGRiBhcyBlbmQgbWFya2VyCiAgICBtZW1zZXQoQ29sb3JhbnRPcmRlciwgMHhGRiwgY21zTUFYQ0hBTk5FTFMgKiBzaXplb2YoY21zVUludDhOdW1iZXIpKTsKCiAgICBpZiAoaW8gLT5SZWFkKGlvLCBDb2xvcmFudE9yZGVyLCBzaXplb2YoY21zVUludDhOdW1iZXIpLCBDb3VudCkgIT0gQ291bnQpIHsKCiAgICAgICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgKHZvaWQqKSBDb2xvcmFudE9yZGVyKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAqbkl0ZW1zID0gMTsKICAgIHJldHVybiAodm9pZCopIENvbG9yYW50T3JkZXI7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwp9CgpzdGF0aWMKY21zQm9vbCBUeXBlX0NvbG9yYW50T3JkZXJUeXBlX1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNVSW50OE51bWJlciogIENvbG9yYW50T3JkZXIgPSAoY21zVUludDhOdW1iZXIqKSBQdHI7CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgc3osIENvdW50OwoKICAgIC8vIEdldCB0aGUgbGVuZ3RoCiAgICBmb3IgKENvdW50PWk9MDsgaSA8IGNtc01BWENIQU5ORUxTOyBpKyspIHsKICAgICAgICBpZiAoQ29sb3JhbnRPcmRlcltpXSAhPSAweEZGKSBDb3VudCsrOwogICAgfQoKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBDb3VudCkpIHJldHVybiBGQUxTRTsKCiAgICBzeiA9IENvdW50ICogc2l6ZW9mKGNtc1VJbnQ4TnVtYmVyKTsKICAgIGlmICghaW8gLT4gV3JpdGUoaW8sIHN6LCBDb2xvcmFudE9yZGVyKSkgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBUUlVFOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCnN0YXRpYwp2b2lkKiBUeXBlX0NvbG9yYW50T3JkZXJUeXBlX0R1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgIHJldHVybiBfY21zRHVwTWVtKHNlbGYgLT5Db250ZXh0SUQsIFB0ciwgY21zTUFYQ0hBTk5FTFMgKiBzaXplb2YoY21zVUludDhOdW1iZXIpKTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG4pOwp9CgoKc3RhdGljCnZvaWQgVHlwZV9Db2xvcmFudE9yZGVyVHlwZV9GcmVlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgdm9pZCogUHRyKQp7CiAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBQdHIpOwp9CgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUeXBlIGNtc1NpZ1MxNUZpeGVkMTZBcnJheVR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVGhpcyB0eXBlIHJlcHJlc2VudHMgYW4gYXJyYXkgb2YgZ2VuZXJpYyA0LWJ5dGUvMzItYml0IGZpeGVkIHBvaW50IHF1YW50aXR5LgovLyBUaGUgbnVtYmVyIG9mIHZhbHVlcyBpcyBkZXRlcm1pbmVkIGZyb20gdGhlIHNpemUgb2YgdGhlIHRhZy4KCnN0YXRpYwp2b2lkICpUeXBlX1MxNUZpeGVkMTZfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNGbG9hdDY0TnVtYmVyKiAgYXJyYXlfZG91YmxlOwogICAgY21zVUludDMyTnVtYmVyIGksIG47CgogICAgKm5JdGVtcyA9IDA7CiAgICBuID0gU2l6ZU9mVGFnIC8gc2l6ZW9mKGNtc1VJbnQzMk51bWJlcik7CiAgICBhcnJheV9kb3VibGUgPSAoY21zRmxvYXQ2NE51bWJlciopIF9jbXNDYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgbiwgc2l6ZW9mKGNtc0Zsb2F0NjROdW1iZXIpKTsKICAgIGlmIChhcnJheV9kb3VibGUgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgZm9yIChpPTA7IGkgPCBuOyBpKyspIHsKCiAgICAgICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJmFycmF5X2RvdWJsZVtpXSkpIHsKCiAgICAgICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIGFycmF5X2RvdWJsZSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICAqbkl0ZW1zID0gbjsKICAgIHJldHVybiAodm9pZCopIGFycmF5X2RvdWJsZTsKfQoKc3RhdGljCmNtc0Jvb2wgVHlwZV9TMTVGaXhlZDE2X1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNGbG9hdDY0TnVtYmVyKiBWYWx1ZSA9IChjbXNGbG9hdDY0TnVtYmVyKikgUHRyOwogICAgY21zVUludDMyTnVtYmVyIGk7CgogICAgZm9yIChpPTA7IGkgPCBuSXRlbXM7IGkrKykgewoKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgVmFsdWVbaV0pKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKc3RhdGljCnZvaWQqIFR5cGVfUzE1Rml4ZWQxNl9EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkICpQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICByZXR1cm4gX2Ntc0R1cE1lbShzZWxmIC0+Q29udGV4dElELCBQdHIsIG4gKiBzaXplb2YoY21zRmxvYXQ2NE51bWJlcikpOwp9CgoKc3RhdGljCnZvaWQgVHlwZV9TMTVGaXhlZDE2X0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFB0cik7Cn0KCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFR5cGUgY21zU2lnVTE2Rml4ZWQxNkFycmF5VHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUaGlzIHR5cGUgcmVwcmVzZW50cyBhbiBhcnJheSBvZiBnZW5lcmljIDQtYnl0ZS8zMi1iaXQgcXVhbnRpdHkuCi8vIFRoZSBudW1iZXIgb2YgdmFsdWVzIGlzIGRldGVybWluZWQgZnJvbSB0aGUgc2l6ZSBvZiB0aGUgdGFnLgoKCnN0YXRpYwp2b2lkICpUeXBlX1UxNkZpeGVkMTZfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNGbG9hdDY0TnVtYmVyKiAgYXJyYXlfZG91YmxlOwogICAgY21zVUludDMyTnVtYmVyIHY7CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgbjsKCiAgICAqbkl0ZW1zID0gMDsKICAgIG4gPSBTaXplT2ZUYWcgLyBzaXplb2YoY21zVUludDMyTnVtYmVyKTsKICAgIGFycmF5X2RvdWJsZSA9IChjbXNGbG9hdDY0TnVtYmVyKikgX2Ntc0NhbGxvYyhzZWxmIC0+Q29udGV4dElELCBuLCBzaXplb2YoY21zRmxvYXQ2NE51bWJlcikpOwogICAgaWYgKGFycmF5X2RvdWJsZSA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBmb3IgKGk9MDsgaSA8IG47IGkrKykgewoKICAgICAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmdikpIHsKICAgICAgICAgICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgKHZvaWQqKSBhcnJheV9kb3VibGUpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgIC8vIENvbnZlcnQgdG8gY21zRmxvYXQ2NE51bWJlcgogICAgICAgIGFycmF5X2RvdWJsZVtpXSA9ICAoY21zRmxvYXQ2NE51bWJlcikgKHYgLyA2NTUzNi4wKTsKICAgIH0KCiAgICAqbkl0ZW1zID0gbjsKICAgIHJldHVybiAodm9pZCopIGFycmF5X2RvdWJsZTsKfQoKc3RhdGljCmNtc0Jvb2wgVHlwZV9VMTZGaXhlZDE2X1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNGbG9hdDY0TnVtYmVyKiBWYWx1ZSA9IChjbXNGbG9hdDY0TnVtYmVyKikgUHRyOwogICAgY21zVUludDMyTnVtYmVyIGk7CgogICAgZm9yIChpPTA7IGkgPCBuSXRlbXM7IGkrKykgewoKICAgICAgICBjbXNVSW50MzJOdW1iZXIgdiA9IChjbXNVSW50MzJOdW1iZXIpIGZsb29yKFZhbHVlW2ldKjY1NTM2LjAgKyAwLjUpOwoKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgdikpIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKc3RhdGljCnZvaWQqIFR5cGVfVTE2Rml4ZWQxNl9EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkICpQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICByZXR1cm4gX2Ntc0R1cE1lbShzZWxmIC0+Q29udGV4dElELCBQdHIsIG4gKiBzaXplb2YoY21zRmxvYXQ2NE51bWJlcikpOwp9CgpzdGF0aWMKdm9pZCBUeXBlX1UxNkZpeGVkMTZfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQqIFB0cikKewogICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgUHRyKTsKfQoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBjbXNTaWdTaWduYXR1cmVUeXBlCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vCi8vIFRoZSBzaWduYXR1cmVUeXBlIGNvbnRhaW5zIGEgZm91ci1ieXRlIHNlcXVlbmNlLCBTZXF1ZW5jZXMgb2YgbGVzcyB0aGFuIGZvdXIKLy8gY2hhcmFjdGVycyBhcmUgcGFkZGVkIGF0IHRoZSBlbmQgd2l0aCBzcGFjZXMsIDIwaC4KLy8gVHlwaWNhbGx5IHRoaXMgdHlwZSBpcyB1c2VkIGZvciByZWdpc3RlcmVkIHRhZ3MgdGhhdCBjYW4gYmUgZGlzcGxheWVkIG9uIG1hbnkKLy8gZGV2ZWxvcG1lbnQgc3lzdGVtcyBhcyBhIHNlcXVlbmNlIG9mIGZvdXIgY2hhcmFjdGVycy4KCnN0YXRpYwp2b2lkICpUeXBlX1NpZ25hdHVyZV9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc1NpZ25hdHVyZSogU2lnUHRyID0gKGNtc1NpZ25hdHVyZSopIF9jbXNNYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgc2l6ZW9mKGNtc1NpZ25hdHVyZSkpOwogICAgaWYgKFNpZ1B0ciA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgU2lnUHRyKSkgcmV0dXJuIE5VTEw7CiAgICAgKm5JdGVtcyA9IDE7CgogICAgIHJldHVybiBTaWdQdHI7CgogICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoU2l6ZU9mVGFnKTsKfQoKc3RhdGljCmNtc0Jvb2wgIFR5cGVfU2lnbmF0dXJlX1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNTaWduYXR1cmUqIFNpZ1B0ciA9IChjbXNTaWduYXR1cmUqKSBQdHI7CgogICAgcmV0dXJuIF9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgKlNpZ1B0cik7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuSXRlbXMpOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKc3RhdGljCnZvaWQqIFR5cGVfU2lnbmF0dXJlX0R1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgIHJldHVybiBfY21zRHVwTWVtKHNlbGYgLT5Db250ZXh0SUQsIFB0ciwgbiAqIHNpemVvZihjbXNTaWduYXR1cmUpKTsKfQoKc3RhdGljCnZvaWQgVHlwZV9TaWduYXR1cmVfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQqIFB0cikKewogICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgUHRyKTsKfQoKCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFR5cGUgY21zU2lnVGV4dFR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8KLy8gVGhlIHRleHRUeXBlIGlzIGEgc2ltcGxlIHRleHQgc3RydWN0dXJlIHRoYXQgY29udGFpbnMgYSA3LWJpdCBBU0NJSSB0ZXh0IHN0cmluZy4KLy8gVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIGlzIG9idGFpbmVkIGJ5IHN1YnRyYWN0aW5nIDggZnJvbSB0aGUgZWxlbWVudCBzaXplIHBvcnRpb24KLy8gb2YgdGhlIHRhZyBpdHNlbGYuIFRoaXMgc3RyaW5nIG11c3QgYmUgdGVybWluYXRlZCB3aXRoIGEgMDBoIGJ5dGUuCgpzdGF0aWMKdm9pZCAqVHlwZV9UZXh0X1JlYWQoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNVSW50MzJOdW1iZXIqIG5JdGVtcywgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY2hhciogVGV4dCA9IE5VTEw7CiAgICBjbXNNTFUqIG1sdSA9IE5VTEw7CgogICAgLy8gQ3JlYXRlIGEgY29udGFpbmVyCiAgICBtbHUgPSBjbXNNTFVhbGxvYyhzZWxmIC0+Q29udGV4dElELCAxKTsKICAgIGlmIChtbHUgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgKm5JdGVtcyA9IDA7CgogICAgLy8gV2UgbmVlZCB0byBzdG9yZSB0aGUgIlwwIiBhdCB0aGUgZW5kLCBzbyArMQogICAgaWYgKFNpemVPZlRhZyA9PSBVSU5UX01BWCkgZ290byBFcnJvcjsKCiAgICBUZXh0ID0gKGNoYXIqKSBfY21zTWFsbG9jKHNlbGYgLT5Db250ZXh0SUQsIFNpemVPZlRhZyArIDEpOwogICAgaWYgKFRleHQgPT0gTlVMTCkgZ290byBFcnJvcjsKCiAgICBpZiAoaW8gLT4gUmVhZChpbywgVGV4dCwgc2l6ZW9mKGNoYXIpLCBTaXplT2ZUYWcpICE9IFNpemVPZlRhZykgZ290byBFcnJvcjsKCiAgICAvLyBNYWtlIHN1cmUgdGV4dCBpcyBwcm9wZXJseSBlbmRlZAogICAgVGV4dFtTaXplT2ZUYWddID0gMDsKICAgICpuSXRlbXMgPSAxOwoKICAgIC8vIEtlZXAgdGhlIHJlc3VsdAogICAgaWYgKCFjbXNNTFVzZXRBU0NJSShtbHUsIGNtc05vTGFuZ3VhZ2UsIGNtc05vQ291bnRyeSwgVGV4dCkpIGdvdG8gRXJyb3I7CgogICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgVGV4dCk7CiAgICByZXR1cm4gKHZvaWQqKSBtbHU7CgpFcnJvcjoKICAgIGlmIChtbHUgIT0gTlVMTCkKICAgICAgICBjbXNNTFVmcmVlKG1sdSk7CiAgICBpZiAoVGV4dCAhPSBOVUxMKQogICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFRleHQpOwoKICAgIHJldHVybiBOVUxMOwp9CgovLyBUaGUgY29udmVyc2lvbiBpbXBsaWVzIHRvIGNob29zZSBhIGxhbmd1YWdlLiBTbywgd2UgY2hvb3NlIHRoZSBhY3R1YWwgbGFuZ3VhZ2UuCnN0YXRpYwpjbXNCb29sIFR5cGVfVGV4dF9Xcml0ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIHZvaWQqIFB0ciwgY21zVUludDMyTnVtYmVyIG5JdGVtcykKewogICAgY21zTUxVKiBtbHUgPSAoY21zTUxVKikgUHRyOwogICAgY21zVUludDMyTnVtYmVyIHNpemU7CiAgICBjbXNCb29sICByYzsKICAgIGNoYXIqIFRleHQ7CgogICAgLy8gR2V0IHRoZSBzaXplIG9mIHRoZSBzdHJpbmcuIE5vdGUgdGhlcmUgaXMgYW4gZXh0cmEgIlwwIiBhdCB0aGUgZW5kCiAgICBzaXplID0gY21zTUxVZ2V0QVNDSUkobWx1LCBjbXNOb0xhbmd1YWdlLCBjbXNOb0NvdW50cnksIE5VTEwsIDApOwogICAgaWYgKHNpemUgPT0gMCkgcmV0dXJuIEZBTFNFOyAgICAgICAvLyBDYW5ub3QgYmUgemVybyEKCiAgICAvLyBDcmVhdGUgbWVtb3J5CiAgICBUZXh0ID0gKGNoYXIqKSBfY21zTWFsbG9jKHNlbGYgLT5Db250ZXh0SUQsIHNpemUpOwogICAgaWYgKFRleHQgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgIGNtc01MVWdldEFTQ0lJKG1sdSwgY21zTm9MYW5ndWFnZSwgY21zTm9Db3VudHJ5LCBUZXh0LCBzaXplKTsKCiAgICAvLyBXcml0ZSBpdCwgaW5jbHVkaW5nIHNlcGFyYXRvcgogICAgcmMgPSBpbyAtPldyaXRlKGlvLCBzaXplLCBUZXh0KTsKCiAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBUZXh0KTsKICAgIHJldHVybiByYzsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7Cn0KCnN0YXRpYwp2b2lkKiBUeXBlX1RleHRfRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCAqUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICAgcmV0dXJuICh2b2lkKikgY21zTUxVZHVwKChjbXNNTFUqKSBQdHIpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKc3RhdGljCnZvaWQgVHlwZV9UZXh0X0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIGNtc01MVSogbWx1ID0gKGNtc01MVSopIFB0cjsKICAgIGNtc01MVWZyZWUobWx1KTsKICAgIHJldHVybjsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgpzdGF0aWMKY21zVGFnVHlwZVNpZ25hdHVyZSBEZWNpZGVUZXh0VHlwZShjbXNGbG9hdDY0TnVtYmVyIElDQ1ZlcnNpb24sIGNvbnN0IHZvaWQgKkRhdGEpCnsKICAgIGlmIChJQ0NWZXJzaW9uID49IDQuMCkKICAgICAgICByZXR1cm4gY21zU2lnTXVsdGlMb2NhbGl6ZWRVbmljb2RlVHlwZTsKCiAgICByZXR1cm4gY21zU2lnVGV4dFR5cGU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihEYXRhKTsKfQoKCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFR5cGUgY21zU2lnRGF0YVR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCi8vIEdlbmVyYWwgcHVycG9zZSBkYXRhIHR5cGUKc3RhdGljCnZvaWQgKlR5cGVfRGF0YV9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc0lDQ0RhdGEqIEJpbkRhdGE7CiAgICBjbXNVSW50MzJOdW1iZXIgTGVuT2ZEYXRhOwoKICAgICpuSXRlbXMgPSAwOwoKICAgIGlmIChTaXplT2ZUYWcgPCBzaXplb2YoY21zVUludDMyTnVtYmVyKSkgcmV0dXJuIE5VTEw7CgogICAgTGVuT2ZEYXRhID0gU2l6ZU9mVGFnIC0gc2l6ZW9mKGNtc1VJbnQzMk51bWJlcik7CiAgICBpZiAoTGVuT2ZEYXRhID4gSU5UX01BWCkgcmV0dXJuIE5VTEw7CgogICAgQmluRGF0YSA9IChjbXNJQ0NEYXRhKikgX2Ntc01hbGxvYyhzZWxmIC0+Q29udGV4dElELCBzaXplb2YoY21zSUNDRGF0YSkgKyBMZW5PZkRhdGEgLSAxKTsKICAgIGlmIChCaW5EYXRhID09IE5VTEwpIHJldHVybiBOVUxMOwoKICAgIEJpbkRhdGEgLT5sZW4gPSBMZW5PZkRhdGE7CiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmQmluRGF0YS0+ZmxhZykpIHsKICAgICAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBCaW5EYXRhKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoaW8gLT4gUmVhZChpbywgQmluRGF0YSAtPmRhdGEsIHNpemVvZihjbXNVSW50OE51bWJlciksIExlbk9mRGF0YSkgIT0gTGVuT2ZEYXRhKSB7CgogICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIEJpbkRhdGEpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgICpuSXRlbXMgPSAxOwoKICAgIHJldHVybiAodm9pZCopIEJpbkRhdGE7Cn0KCgpzdGF0aWMKY21zQm9vbCBUeXBlX0RhdGFfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgY21zSUNDRGF0YSogQmluRGF0YSA9IChjbXNJQ0NEYXRhKikgUHRyOwoKICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIEJpbkRhdGEgLT5mbGFnKSkgcmV0dXJuIEZBTFNFOwoKICAgcmV0dXJuIGlvIC0+V3JpdGUoaW8sIEJpbkRhdGEgLT5sZW4sIEJpbkRhdGEgLT5kYXRhKTsKCiAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKCnN0YXRpYwp2b2lkKiBUeXBlX0RhdGFfRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCAqUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICAgY21zSUNDRGF0YSogQmluRGF0YSA9IChjbXNJQ0NEYXRhKikgUHRyOwoKICAgIHJldHVybiBfY21zRHVwTWVtKHNlbGYgLT5Db250ZXh0SUQsIFB0ciwgc2l6ZW9mKGNtc0lDQ0RhdGEpICsgQmluRGF0YSAtPmxlbiAtIDEpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7Cn0KCnN0YXRpYwp2b2lkIFR5cGVfRGF0YV9GcmVlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgdm9pZCogUHRyKQp7CiAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBQdHIpOwp9CgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUeXBlIGNtc1NpZ1RleHREZXNjcmlwdGlvblR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCnN0YXRpYwp2b2lkICpUeXBlX1RleHRfRGVzY3JpcHRpb25fUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjaGFyKiBUZXh0ID0gTlVMTDsKICAgIGNtc01MVSogbWx1ID0gTlVMTDsKICAgIGNtc1VJbnQzMk51bWJlciAgQXNjaWlDb3VudDsKICAgIGNtc1VJbnQzMk51bWJlciAgaSwgVW5pY29kZUNvZGUsIFVuaWNvZGVDb3VudDsKICAgIGNtc1VJbnQxNk51bWJlciAgU2NyaXB0Q29kZUNvZGUsIER1bW15OwogICAgY21zVUludDhOdW1iZXIgICBTY3JpcHRDb2RlQ291bnQ7CgogICAgKm5JdGVtcyA9IDA7CgogICAgLy8gIE9uZSBkd29yZCBzaG91bGQgYmUgdGhlcmUKICAgIGlmIChTaXplT2ZUYWcgPCBzaXplb2YoY21zVUludDMyTnVtYmVyKSkgcmV0dXJuIE5VTEw7CgogICAgLy8gUmVhZCBsZW4gb2YgQVNDSUkKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZBc2NpaUNvdW50KSkgcmV0dXJuIE5VTEw7CiAgICBTaXplT2ZUYWcgLT0gc2l6ZW9mKGNtc1VJbnQzMk51bWJlcik7CgogICAgLy8gQ2hlY2sgZm9yIHNpemUKICAgIGlmIChTaXplT2ZUYWcgPCBBc2NpaUNvdW50KSByZXR1cm4gTlVMTDsKCiAgICAvLyBBbGwgc2VlbXMgT2ssIGFsbG9jYXRlIHRoZSBjb250YWluZXIKICAgIG1sdSA9IGNtc01MVWFsbG9jKHNlbGYgLT5Db250ZXh0SUQsIDEpOwogICAgaWYgKG1sdSA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICAvLyBBcyBtYW55IG1lbW9yeSBhcyBzaXplIG9mIHRhZwogICAgVGV4dCA9IChjaGFyKikgX2Ntc01hbGxvYyhzZWxmIC0+Q29udGV4dElELCBBc2NpaUNvdW50ICsgMSk7CiAgICBpZiAoVGV4dCA9PSBOVUxMKSBnb3RvIEVycm9yOwoKICAgIC8vIFJlYWQgaXQKICAgIGlmIChpbyAtPlJlYWQoaW8sIFRleHQsIHNpemVvZihjaGFyKSwgQXNjaWlDb3VudCkgIT0gQXNjaWlDb3VudCkgZ290byBFcnJvcjsKICAgIFNpemVPZlRhZyAtPSBBc2NpaUNvdW50OwoKICAgIC8vIE1ha2Ugc3VyZSB0aGVyZSBpcyBhIHRlcm1pbmF0b3IKICAgIFRleHRbQXNjaWlDb3VudF0gPSAwOwoKICAgIC8vIFNldCB0aGUgTUxVIGVudHJ5LiBGcm9tIGhlcmUgd2UgY2FuIGJlIHRvbGVyYW50IHRvIHdyb25nIHR5cGVzCiAgICBpZiAoIWNtc01MVXNldEFTQ0lJKG1sdSwgY21zTm9MYW5ndWFnZSwgY21zTm9Db3VudHJ5LCBUZXh0KSkgZ290byBFcnJvcjsKICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsICh2b2lkKikgVGV4dCk7CiAgICBUZXh0ID0gTlVMTDsKCiAgICAvLyBTa2lwIFVuaWNvZGUgY29kZQogICAgaWYgKFNpemVPZlRhZyA8IDIqIHNpemVvZihjbXNVSW50MzJOdW1iZXIpKSBnb3RvIERvbmU7CiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmVW5pY29kZUNvZGUpKSBnb3RvIERvbmU7CiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmVW5pY29kZUNvdW50KSkgZ290byBEb25lOwogICAgU2l6ZU9mVGFnIC09IDIqIHNpemVvZihjbXNVSW50MzJOdW1iZXIpOwoKICAgIGlmIChTaXplT2ZUYWcgPCBVbmljb2RlQ291bnQqc2l6ZW9mKGNtc1VJbnQxNk51bWJlcikpIGdvdG8gRG9uZTsKCiAgICBmb3IgKGk9MDsgaSA8IFVuaWNvZGVDb3VudDsgaSsrKSB7CiAgICAgICAgaWYgKCFpbyAtPlJlYWQoaW8sICZEdW1teSwgc2l6ZW9mKGNtc1VJbnQxNk51bWJlciksIDEpKSBnb3RvIERvbmU7CiAgICB9CiAgICBTaXplT2ZUYWcgLT0gVW5pY29kZUNvdW50KnNpemVvZihjbXNVSW50MTZOdW1iZXIpOwoKICAgIC8vIFNraXAgU2NyaXB0Q29kZSBjb2RlIGlmIHByZXNlbnQuIFNvbWUgYnVnZ3kgcHJvZmlsZXMgZG9lcyBoYXZlIGxlc3MKICAgIC8vIGRhdGEgdGhhdCBzdHJpY3R0bHkgcmVxdWlyZWQuIFdlIG5lZWQgdG8gc2tpcCBpdCBhcyB0aGlzIHR5cGUgbWF5IGNvbWUKICAgIC8vIGVtYmVkZGVkIGluIG90aGVyIHR5cGVzLgoKICAgIGlmIChTaXplT2ZUYWcgPj0gc2l6ZW9mKGNtc1VJbnQxNk51bWJlcikgKyBzaXplb2YoY21zVUludDhOdW1iZXIpICsgNjcpIHsKCiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJlNjcmlwdENvZGVDb2RlKSkgZ290byBEb25lOwogICAgICAgIGlmICghX2Ntc1JlYWRVSW50OE51bWJlcihpbywgICZTY3JpcHRDb2RlQ291bnQpKSBnb3RvIERvbmU7CgogICAgICAgIC8vIFNraXAgcmVzdCBvZiB0YWcKICAgICAgICBmb3IgKGk9MDsgaSA8IDY3OyBpKyspIHsKICAgICAgICAgICAgaWYgKCFpbyAtPlJlYWQoaW8sICZEdW1teSwgc2l6ZW9mKGNtc1VJbnQ4TnVtYmVyKSwgMSkpIGdvdG8gRXJyb3I7CiAgICAgICAgfQogICAgfQoKRG9uZToKCiAgICAqbkl0ZW1zID0gMTsKICAgIHJldHVybiBtbHU7CgpFcnJvcjoKICAgIGlmIChUZXh0KSBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCAodm9pZCopIFRleHQpOwogICAgaWYgKG1sdSkgY21zTUxVZnJlZShtbHUpOwogICAgcmV0dXJuIE5VTEw7Cn0KCgovLyBUaGlzIHRhZyBjYW4gY29tZSBJTiBVTkFMSUdORUQgU0laRS4gSW4gb3JkZXIgdG8gcHJldmVudCBpc3N1ZXMsIHdlIGZvcmNlIHplcm9zIG9uIGRlc2NyaXB0aW9uIHRvIGFsaWduIGl0CnN0YXRpYwpjbXNCb29sICBUeXBlX1RleHRfRGVzY3JpcHRpb25fV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc01MVSogbWx1ID0gKGNtc01MVSopIFB0cjsKICAgIGNoYXIgKlRleHQgPSBOVUxMOwogICAgd2NoYXJfdCAqV2lkZSA9IE5VTEw7CiAgICBjbXNVSW50MzJOdW1iZXIgbGVuLCBsZW5fYWxpZ25lZCwgbGVuX2ZpbGxlcl9hbGlnbm1lbnQ7CiAgICBjbXNCb29sICByYyA9IEZBTFNFOwogICAgY2hhciBGaWxsZXJbNjhdOwoKICAgIC8vIFVzZWQgYmVsb3cgZm9yIHdyaXR0aW5nIHplcm9lcwogICAgbWVtc2V0KEZpbGxlciwgMCwgc2l6ZW9mKEZpbGxlcikpOwoKICAgIC8vIEdldCB0aGUgbGVuIG9mIHN0cmluZwogICAgbGVuID0gY21zTUxVZ2V0QVNDSUkobWx1LCBjbXNOb0xhbmd1YWdlLCBjbXNOb0NvdW50cnksIE5VTEwsIDApOwoKICAgIC8vIEZyb20gSUNDMy40OiBJdCBoYXMgYmVlbiBmb3VuZCB0aGF0IHRleHREZXNjcmlwdGlvblR5cGUgY2FuIGNvbnRhaW4gbWlzYWxpZ25lZCBkYXRhCiAgICAvLyhzZWUgY2xhdXNlIDQuMSBmb3IgdGhlIGRlZmluaXRpb24gb2Ygk2FsaWduZWQ/LiBCZWNhdXNlIHRoZSBVbmljb2RlIGxhbmd1YWdlCiAgICAvLyBjb2RlIGFuZCBVbmljb2RlIGNvdW50IGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgQVNDSUkgZGVzY3JpcHRpb24sIHRoZWlyCiAgICAvLyBhbGlnbm1lbnQgaXMgbm90IGNvcnJlY3QgaWYgdGhlIEFTQ0lJIGNvdW50IGlzIG5vdCBhIG11bHRpcGxlIG9mIGZvdXIuIFRoZQogICAgLy8gU2NyaXB0Q29kZSBjb2RlIGlzIG1pc2FsaWduZWQgd2hlbiB0aGUgQVNDSUkgY291bnQgaXMgb2RkLiBQcm9maWxlIHJlYWRpbmcgYW5kCiAgICAvLyB3cml0aW5nIHNvZnR3YXJlIG11c3QgYmUgd3JpdHRlbiBjYXJlZnVsbHkgaW4gb3JkZXIgdG8gaGFuZGxlIHRoZXNlIGFsaWdubWVudAogICAgLy8gcHJvYmxlbXMuCgogICAgLy8gQ29tcHV0ZSBhbiBhbGlnbmVkIHNpemUKICAgIGxlbl9hbGlnbmVkID0gX2Ntc0FMSUdOTE9ORyhsZW4pOwogICAgbGVuX2ZpbGxlcl9hbGlnbm1lbnQgPSBsZW5fYWxpZ25lZCAtIGxlbjsKCiAgICAvLyBOdWxsIHN0cmluZ3MKICAgIGlmIChsZW4gPD0gMCkgewoKICAgICAgICBUZXh0ID0gKGNoYXIqKSAgICBfY21zRHVwTWVtKHNlbGYgLT5Db250ZXh0SUQsICIiLCBzaXplb2YoY2hhcikpOwogICAgICAgIFdpZGUgPSAod2NoYXJfdCopIF9jbXNEdXBNZW0oc2VsZiAtPkNvbnRleHRJRCwgTCIiLCBzaXplb2Yod2NoYXJfdCkpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgLy8gQ3JlYXRlIGluZGVwZW5kZW50IGJ1ZmZlcnMKICAgICAgICBUZXh0ID0gKGNoYXIqKSBfY21zQ2FsbG9jKHNlbGYgLT5Db250ZXh0SUQsIGxlbiwgc2l6ZW9mKGNoYXIpKTsKICAgICAgICBpZiAoVGV4dCA9PSBOVUxMKSBnb3RvIEVycm9yOwoKICAgICAgICBXaWRlID0gKHdjaGFyX3QqKSBfY21zQ2FsbG9jKHNlbGYgLT5Db250ZXh0SUQsIGxlbiwgc2l6ZW9mKHdjaGFyX3QpKTsKICAgICAgICBpZiAoV2lkZSA9PSBOVUxMKSBnb3RvIEVycm9yOwoKICAgICAgICAvLyBHZXQgYm90aCByZXByZXNlbnRhdGlvbnMuCiAgICAgICAgY21zTUxVZ2V0QVNDSUkobWx1LCBjbXNOb0xhbmd1YWdlLCBjbXNOb0NvdW50cnksICBUZXh0LCBsZW4gKiBzaXplb2YoY2hhcikpOwogICAgICAgIGNtc01MVWdldFdpZGUobWx1LCAgY21zTm9MYW5ndWFnZSwgY21zTm9Db3VudHJ5LCAgV2lkZSwgbGVuICogc2l6ZW9mKHdjaGFyX3QpKTsKICAgIH0KCiAgLy8gKiBjbXNVSW50MzJOdW1iZXIgICAgICAgY291bnQ7ICAgICAgICAgICogRGVzY3JpcHRpb24gbGVuZ3RoCiAgLy8gKiBjbXNJbnQ4TnVtYmVyICAgICAgICAgZGVzY1tjb3VudF0gICAgICogTlVMTCB0ZXJtaW5hdGVkIGFzY2lpIHN0cmluZwogIC8vICogY21zVUludDMyTnVtYmVyICAgICAgIHVjTGFuZ0NvZGU7ICAgICAqIFVuaUNvZGUgbGFuZ3VhZ2UgY29kZQogIC8vICogY21zVUludDMyTnVtYmVyICAgICAgIHVjQ291bnQ7ICAgICAgICAqIFVuaUNvZGUgZGVzY3JpcHRpb24gbGVuZ3RoCiAgLy8gKiBjbXNJbnQxNk51bWJlciAgICAgICAgdWNEZXNjW3VjQ291bnRdOyogVGhlIFVuaUNvZGUgZGVzY3JpcHRpb24KICAvLyAqIGNtc1VJbnQxNk51bWJlciAgICAgICBzY0NvZGU7ICAgICAgICAgKiBTY3JpcHRDb2RlIGNvZGUKICAvLyAqIGNtc1VJbnQ4TnVtYmVyICAgICAgICBzY0NvdW50OyAgICAgICAgKiBTY3JpcHRDb2RlIGNvdW50CiAgLy8gKiBjbXNJbnQ4TnVtYmVyICAgICAgICAgc2NEZXNjWzY3XTsgICAgICogU2NyaXB0Q29kZSBEZXNjcmlwdGlvbgoKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBsZW5fYWxpZ25lZCkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIWlvIC0+V3JpdGUoaW8sIGxlbiwgVGV4dCkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIWlvIC0+V3JpdGUoaW8sIGxlbl9maWxsZXJfYWxpZ25tZW50LCBGaWxsZXIpKSBnb3RvIEVycm9yOwoKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCAwKSkgZ290byBFcnJvcjsgIC8vIHVjTGFuZ3VhZ2VDb2RlCgogICAgLy8gVGhpcyBwYXJ0IGlzIHRyaWNreTogd2UgbmVlZCBhbiBhbGlnbmVkIHRhZyBzaXplLCBhbmQgdGhlIFNjcmlwdENvZGUgcGFydAogICAgLy8gdGFrZXMgNzAgYnl0ZXMsIHNvIHdlIG5lZWQgMiBleHRyYSBieXRlcyB0byBkbyB0aGUgYWxpZ25tZW50CgogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIGxlbl9hbGlnbmVkKzEpKSBnb3RvIEVycm9yOwoKICAgIC8vIE5vdGUgdGhhdCBpbiBzb21lIGNvbXBpbGVycyBzaXplb2YoY21zVUludDE2TnVtYmVyKSAhPSBzaXplb2Yod2NoYXJfdCkKICAgIGlmICghX2Ntc1dyaXRlV0NoYXJBcnJheShpbywgbGVuLCBXaWRlKSkgZ290byBFcnJvcjsKICAgIGlmICghX2Ntc1dyaXRlVUludDE2QXJyYXkoaW8sIGxlbl9maWxsZXJfYWxpZ25tZW50KzEsIChjbXNVSW50MTZOdW1iZXIqKSBGaWxsZXIpKSBnb3RvIEVycm9yOwoKICAgIC8vIFNjcmlwdENvZGUgQ29kZSAmIGNvdW50ICh1bnVzZWQpCiAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgMCkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQ4TnVtYmVyKGlvLCAwKSkgZ290byBFcnJvcjsKCiAgICBpZiAoIWlvIC0+V3JpdGUoaW8sIDY3LCBGaWxsZXIpKSBnb3RvIEVycm9yOwoKICAgIHJjID0gVFJVRTsKCkVycm9yOgogICAgaWYgKFRleHQpIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFRleHQpOwogICAgaWYgKFdpZGUpIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFdpZGUpOwoKICAgIHJldHVybiByYzsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7Cn0KCgpzdGF0aWMKdm9pZCogVHlwZV9UZXh0X0Rlc2NyaXB0aW9uX0R1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgIHJldHVybiAodm9pZCopIGNtc01MVWR1cCgoY21zTUxVKikgUHRyKTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG4pOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKc3RhdGljCnZvaWQgVHlwZV9UZXh0X0Rlc2NyaXB0aW9uX0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIGNtc01MVSogbWx1ID0gKGNtc01MVSopIFB0cjsKCiAgICBjbXNNTFVmcmVlKG1sdSk7CiAgICByZXR1cm47CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKCnN0YXRpYwpjbXNUYWdUeXBlU2lnbmF0dXJlIERlY2lkZVRleHREZXNjVHlwZShjbXNGbG9hdDY0TnVtYmVyIElDQ1ZlcnNpb24sIGNvbnN0IHZvaWQgKkRhdGEpCnsKICAgIGlmIChJQ0NWZXJzaW9uID49IDQuMCkKICAgICAgICByZXR1cm4gY21zU2lnTXVsdGlMb2NhbGl6ZWRVbmljb2RlVHlwZTsKCiAgICByZXR1cm4gY21zU2lnVGV4dERlc2NyaXB0aW9uVHlwZTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKERhdGEpOwp9CgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBjbXNTaWdDdXJ2ZVR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCnN0YXRpYwp2b2lkICpUeXBlX0N1cnZlX1JlYWQoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNVSW50MzJOdW1iZXIqIG5JdGVtcywgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY21zVUludDMyTnVtYmVyIENvdW50OwogICAgY21zVG9uZUN1cnZlKiBOZXdHYW1tYTsKICAgIAogICAgKm5JdGVtcyA9IDA7CiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmQ291bnQpKSByZXR1cm4gTlVMTDsKCiAgICBzd2l0Y2ggKENvdW50KSB7CgogICAgICAgICAgIGNhc2UgMDogICAvLyBMaW5lYXIuCiAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIGNtc0Zsb2F0NjROdW1iZXIgU2luZ2xlR2FtbWEgPSAxLjA7CgogICAgICAgICAgICAgICAgICAgTmV3R2FtbWEgPSBjbXNCdWlsZFBhcmFtZXRyaWNUb25lQ3VydmUoc2VsZiAtPkNvbnRleHRJRCwgMSwgJlNpbmdsZUdhbW1hKTsKICAgICAgICAgICAgICAgICAgIGlmICghTmV3R2FtbWEpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgICAgKm5JdGVtcyA9IDE7CiAgICAgICAgICAgICAgICAgICByZXR1cm4gTmV3R2FtbWE7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAKICAgICAgICAgICBjYXNlIDE6ICAvLyBTcGVjaWZpZWQgYXMgdGhlIGV4cG9uZW50IG9mIGdhbW1hIGZ1bmN0aW9uCiAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIGNtc1VJbnQxNk51bWJlciBTaW5nbGVHYW1tYUZpeGVkOwogICAgICAgICAgICAgICAgICAgY21zRmxvYXQ2NE51bWJlciBTaW5nbGVHYW1tYTsKCiAgICAgICAgICAgICAgICAgICBpZiAoIV9jbXNSZWFkVUludDE2TnVtYmVyKGlvLCAmU2luZ2xlR2FtbWFGaXhlZCkpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgICAgU2luZ2xlR2FtbWEgPSBfY21zOEZpeGVkOHRvRG91YmxlKFNpbmdsZUdhbW1hRml4ZWQpOwoKICAgICAgICAgICAgICAgICAgICpuSXRlbXMgPSAxOwogICAgICAgICAgICAgICAgICAgcmV0dXJuIGNtc0J1aWxkUGFyYW1ldHJpY1RvbmVDdXJ2ZShzZWxmIC0+Q29udGV4dElELCAxLCAmU2luZ2xlR2FtbWEpOwogICAgICAgICAgICAgICB9CgogICAgICAgICAgIGRlZmF1bHQ6ICAvLyBDdXJ2ZQoKICAgICAgICAgICAgICAgaWYgKENvdW50ID4gMHg3RkZGKQogICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7IC8vIFRoaXMgaXMgdG8gcHJldmVudCBiYWQgZ3V5cyBmb3IgZG9pbmcgYmFkIHRoaW5ncwoKICAgICAgICAgICAgICAgTmV3R2FtbWEgPSBjbXNCdWlsZFRhYnVsYXRlZFRvbmVDdXJ2ZTE2KHNlbGYgLT5Db250ZXh0SUQsIENvdW50LCBOVUxMKTsKICAgICAgICAgICAgICAgaWYgKCFOZXdHYW1tYSkgcmV0dXJuIE5VTEw7CgogICAgICAgICAgICAgICBpZiAoIV9jbXNSZWFkVUludDE2QXJyYXkoaW8sIENvdW50LCBOZXdHYW1tYSAtPiBUYWJsZTE2KSkgcmV0dXJuIE5VTEw7CgogICAgICAgICAgICAgICAqbkl0ZW1zID0gMTsKICAgICAgICAgICAgICAgcmV0dXJuIE5ld0dhbW1hOwogICAgfQoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoU2l6ZU9mVGFnKTsKfQoKCnN0YXRpYwpjbXNCb29sICBUeXBlX0N1cnZlX1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNUb25lQ3VydmUqIEN1cnZlID0gKGNtc1RvbmVDdXJ2ZSopIFB0cjsKCiAgICBpZiAoQ3VydmUgLT5uU2VnbWVudHMgPT0gMSAmJiBDdXJ2ZSAtPlNlZ21lbnRzWzBdLlR5cGUgPT0gMSkgewoKICAgICAgICAgICAgLy8gU2luZ2xlIGdhbW1hLCBwcmVzZXJ2ZSBudW1iZXIKICAgICAgICAgICAgY21zVUludDE2TnVtYmVyIFNpbmdsZUdhbW1hRml4ZWQgPSBfY21zRG91YmxlVG84Rml4ZWQ4KEN1cnZlIC0+U2VnbWVudHNbMF0uUGFyYW1zWzBdKTsKCiAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCAxKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgU2luZ2xlR2FtbWFGaXhlZCkpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgfQoKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBDdXJ2ZSAtPm5FbnRyaWVzKSkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIF9jbXNXcml0ZVVJbnQxNkFycmF5KGlvLCBDdXJ2ZSAtPm5FbnRyaWVzLCBDdXJ2ZSAtPlRhYmxlMTYpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCgpzdGF0aWMKdm9pZCogVHlwZV9DdXJ2ZV9EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkICpQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICByZXR1cm4gKHZvaWQqKSBjbXNEdXBUb25lQ3VydmUoKGNtc1RvbmVDdXJ2ZSopIFB0cik7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCnN0YXRpYwp2b2lkIFR5cGVfQ3VydmVfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQqIFB0cikKewogICAgY21zVG9uZUN1cnZlKiBnYW1tYSA9IChjbXNUb25lQ3VydmUqKSBQdHI7CgogICAgY21zRnJlZVRvbmVDdXJ2ZShnYW1tYSk7CiAgICByZXR1cm47CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFR5cGUgY21zU2lnUGFyYW1ldHJpY0N1cnZlVHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKCi8vIERlY2lkZSB3aGljaCBjdXJ2ZSB0eXBlIHRvIHVzZSBvbiB3cml0dGluZwpzdGF0aWMKY21zVGFnVHlwZVNpZ25hdHVyZSBEZWNpZGVDdXJ2ZVR5cGUoY21zRmxvYXQ2NE51bWJlciBJQ0NWZXJzaW9uLCBjb25zdCB2b2lkICpEYXRhKQp7CiAgICBjbXNUb25lQ3VydmUqIEN1cnZlID0gKGNtc1RvbmVDdXJ2ZSopIERhdGE7CgogICAgaWYgKElDQ1ZlcnNpb24gPCA0LjApIHJldHVybiBjbXNTaWdDdXJ2ZVR5cGU7CiAgICBpZiAoQ3VydmUgLT5uU2VnbWVudHMgIT0gMSkgcmV0dXJuIGNtc1NpZ0N1cnZlVHlwZTsgICAgICAgICAgLy8gT25seSAxLXNlZ21lbnQgY3VydmVzIGNhbiBiZSBzYXZlZCBhcyBwYXJhbWV0cmljCiAgICBpZiAoQ3VydmUgLT5TZWdtZW50c1swXS5UeXBlIDwgMCkgcmV0dXJuIGNtc1NpZ0N1cnZlVHlwZTsgICAgLy8gT25seSBub24taW52ZXJ0ZWQgY3VydmVzCiAgICBpZiAoQ3VydmUgLT5TZWdtZW50c1swXS5UeXBlID4gNSkgcmV0dXJuIGNtc1NpZ0N1cnZlVHlwZTsgICAgLy8gT25seSBJQ0MgcGFyYW1ldHJpYyBjdXJ2ZXMKCiAgICByZXR1cm4gY21zU2lnUGFyYW1ldHJpY0N1cnZlVHlwZTsKfQoKc3RhdGljCnZvaWQgKlR5cGVfUGFyYW1ldHJpY0N1cnZlX1JlYWQoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNVSW50MzJOdW1iZXIqIG5JdGVtcywgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgc3RhdGljIGNvbnN0IGludCBQYXJhbXNCeVR5cGVbXSA9IHsgMSwgMywgNCwgNSwgNyB9OwogICAgY21zRmxvYXQ2NE51bWJlciBQYXJhbXNbMTBdOwogICAgY21zVUludDE2TnVtYmVyIFR5cGU7CiAgICBpbnQgaSwgbjsKICAgIGNtc1RvbmVDdXJ2ZSogTmV3R2FtbWE7CgogICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJlR5cGUpKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50MTZOdW1iZXIoaW8sIE5VTEwpKSByZXR1cm4gTlVMTDsgICAvLyBSZXNlcnZlZAoKICAgIGlmIChUeXBlID4gNCkgewoKICAgICAgICBjbXNTaWduYWxFcnJvcihzZWxmLT5Db250ZXh0SUQsIGNtc0VSUk9SX1VOS05PV05fRVhURU5TSU9OLCAiVW5rbm93biBwYXJhbWV0cmljIGN1cnZlIHR5cGUgJyVkJyIsIFR5cGUpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIG1lbXNldChQYXJhbXMsIDAsIHNpemVvZihQYXJhbXMpKTsKICAgIG4gPSBQYXJhbXNCeVR5cGVbVHlwZV07CgogICAgZm9yIChpPTA7IGkgPCBuOyBpKyspIHsKCiAgICAgICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJlBhcmFtc1tpXSkpIHJldHVybiBOVUxMOwogICAgfQoKICAgIE5ld0dhbW1hID0gY21zQnVpbGRQYXJhbWV0cmljVG9uZUN1cnZlKHNlbGYgLT5Db250ZXh0SUQsIFR5cGUrMSwgUGFyYW1zKTsKCiAgICAqbkl0ZW1zID0gMTsKICAgIHJldHVybiBOZXdHYW1tYTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKFNpemVPZlRhZyk7Cn0KCgpzdGF0aWMKY21zQm9vbCAgVHlwZV9QYXJhbWV0cmljQ3VydmVfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc1RvbmVDdXJ2ZSogQ3VydmUgPSAoY21zVG9uZUN1cnZlKikgUHRyOwogICAgaW50IGksIG5QYXJhbXMsIHR5cGVuOwogICAgc3RhdGljIGNvbnN0IGludCBQYXJhbXNCeVR5cGVbXSA9IHsgMCwgMSwgMywgNCwgNSwgNyB9OwoKICAgIHR5cGVuID0gQ3VydmUgLT4gU2VnbWVudHNbMF0uVHlwZTsKCiAgICBpZiAoQ3VydmUgLT5uU2VnbWVudHMgPiAxIHx8IHR5cGVuIDwgMSkgewoKICAgICAgICBjbXNTaWduYWxFcnJvcihzZWxmLT5Db250ZXh0SUQsIGNtc0VSUk9SX1VOS05PV05fRVhURU5TSU9OLCAiTXVsdGlzZWdtZW50IG9yIEludmVydGVkIHBhcmFtZXRyaWMgY3VydmVzIGNhbm5vdCBiZSB3cml0dGVuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICh0eXBlbiA+IDUpIHsKICAgICAgICBjbXNTaWduYWxFcnJvcihzZWxmLT5Db250ZXh0SUQsIGNtc0VSUk9SX1VOS05PV05fRVhURU5TSU9OLCAiVW5zdXBwb3J0ZWQgcGFyYW1ldHJpYyBjdXJ2ZSIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBuUGFyYW1zID0gUGFyYW1zQnlUeXBlW3R5cGVuXTsKCiAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgKGNtc1VJbnQxNk51bWJlcikgKEN1cnZlIC0+U2VnbWVudHNbMF0uVHlwZSAtIDEpKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MTZOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7ICAgICAgICAvLyBSZXNlcnZlZAoKICAgIGZvciAoaT0wOyBpIDwgblBhcmFtczsgaSsrKSB7CgogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBDdXJ2ZSAtPiBTZWdtZW50c1swXS5QYXJhbXNbaV0pKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuSXRlbXMpOwp9CgpzdGF0aWMKdm9pZCogVHlwZV9QYXJhbWV0cmljQ3VydmVfRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCAqUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICAgcmV0dXJuICh2b2lkKikgY21zRHVwVG9uZUN1cnZlKChjbXNUb25lQ3VydmUqKSBQdHIpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgpzdGF0aWMKdm9pZCBUeXBlX1BhcmFtZXRyaWNDdXJ2ZV9GcmVlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgdm9pZCogUHRyKQp7CiAgICBjbXNUb25lQ3VydmUqIGdhbW1hID0gKGNtc1RvbmVDdXJ2ZSopIFB0cjsKCiAgICBjbXNGcmVlVG9uZUN1cnZlKGdhbW1hKTsKICAgIHJldHVybjsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBjbXNTaWdEYXRlVGltZVR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCi8vIEEgMTItYnl0ZSB2YWx1ZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGltZSBhbmQgZGF0ZSwgd2hlcmUgdGhlIGJ5dGUgdXNhZ2UgaXMgYXNzaWduZWQKLy8gYXMgc3BlY2lmaWVkIGluIHRhYmxlIDEuIFRoZSBhY3R1YWwgdmFsdWVzIGFyZSBlbmNvZGVkIGFzIDE2LWJpdCB1bnNpZ25lZCBpbnRlZ2VycwovLyAodUludDE2TnVtYmVyIC0gc2VlIDUuMS42KS4KLy8KLy8gQWxsIHRoZSBkYXRlVGltZU51bWJlciB2YWx1ZXMgaW4gYSBwcm9maWxlIHNoYWxsIGJlIGluIENvb3JkaW5hdGVkIFVuaXZlcnNhbCBUaW1lCi8vIChVVEMsIGFsc28ga25vd24gYXMgR01UIG9yIFpVTFUgVGltZSkuIFByb2ZpbGUgd3JpdGVycyBhcmUgcmVxdWlyZWQgdG8gY29udmVydCBsb2NhbAovLyB0aW1lIHRvIFVUQyB3aGVuIHNldHRpbmcgdGhlc2UgdmFsdWVzLiBQcm9ncmFtbWVzIHRoYXQgZGlzcGxheSB0aGVzZSB2YWx1ZXMgbWF5IHNob3cKLy8gdGhlIGRhdGVUaW1lTnVtYmVyIGFzIFVUQywgc2hvdyB0aGUgZXF1aXZhbGVudCBsb2NhbCB0aW1lIChhdCBjdXJyZW50IGxvY2FsZSksIG9yCi8vIGRpc3BsYXkgYm90aCBVVEMgYW5kIGxvY2FsIHZlcnNpb25zIG9mIHRoZSBkYXRlVGltZU51bWJlci4KCnN0YXRpYwp2b2lkICpUeXBlX0RhdGVUaW1lX1JlYWQoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNVSW50MzJOdW1iZXIqIG5JdGVtcywgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY21zRGF0ZVRpbWVOdW1iZXIgdGltZXN0YW1wOwogICAgc3RydWN0IHRtICogTmV3RGF0ZVRpbWU7CgogICAgKm5JdGVtcyA9IDA7CiAgICBOZXdEYXRlVGltZSA9IChzdHJ1Y3QgdG0qKSBfY21zTWFsbG9jKHNlbGYgLT5Db250ZXh0SUQsIHNpemVvZihzdHJ1Y3QgdG0pKTsKICAgIGlmIChOZXdEYXRlVGltZSA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBpZiAoaW8tPlJlYWQoaW8sICZ0aW1lc3RhbXAsIHNpemVvZihjbXNEYXRlVGltZU51bWJlciksIDEpICE9IDEpIHJldHVybiBOVUxMOwoKICAgICBfY21zRGVjb2RlRGF0ZVRpbWVOdW1iZXIoJnRpbWVzdGFtcCwgTmV3RGF0ZVRpbWUpOwoKICAgICAqbkl0ZW1zID0gMTsKICAgICByZXR1cm4gTmV3RGF0ZVRpbWU7CgogICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoU2l6ZU9mVGFnKTsKfQoKCnN0YXRpYwpjbXNCb29sICBUeXBlX0RhdGVUaW1lX1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBzdHJ1Y3QgdG0gKiBEYXRlVGltZSA9IChzdHJ1Y3QgdG0qKSBQdHI7CiAgICBjbXNEYXRlVGltZU51bWJlciB0aW1lc3RhbXA7CgogICAgX2Ntc0VuY29kZURhdGVUaW1lTnVtYmVyKCZ0aW1lc3RhbXAsIERhdGVUaW1lKTsKICAgIGlmICghaW8gLT5Xcml0ZShpbywgc2l6ZW9mKGNtc0RhdGVUaW1lTnVtYmVyKSwgJnRpbWVzdGFtcCkpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgpzdGF0aWMKdm9pZCogVHlwZV9EYXRlVGltZV9EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkICpQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICByZXR1cm4gX2Ntc0R1cE1lbShzZWxmIC0+Q29udGV4dElELCBQdHIsIHNpemVvZihzdHJ1Y3QgdG0pKTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG4pOwp9CgpzdGF0aWMKdm9pZCBUeXBlX0RhdGVUaW1lX0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFB0cik7Cn0KCgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBpY01lYXN1cmVtZW50VHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKLyoKVGhlIG1lYXN1cmVtZW50VHlwZSBpbmZvcm1hdGlvbiByZWZlcnMgb25seSB0byB0aGUgaW50ZXJuYWwgcHJvZmlsZSBkYXRhIGFuZCBpcwptZWFudCB0byBwcm92aWRlIHByb2ZpbGUgbWFrZXJzIGFuIGFsdGVybmF0aXZlIHRvIHRoZSBkZWZhdWx0IG1lYXN1cmVtZW50CnNwZWNpZmljYXRpb25zLgoqLwoKc3RhdGljCnZvaWQgKlR5cGVfTWVhc3VyZW1lbnRfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNJQ0NNZWFzdXJlbWVudENvbmRpdGlvbnMgbWM7CgoJCiAgICBtZW1zZXQoJm1jLCAwLCBzaXplb2YobWMpKTsKCQogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJm1jLk9ic2VydmVyKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkWFlaTnVtYmVyKGlvLCAgICAmbWMuQmFja2luZykpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJm1jLkdlb21ldHJ5KSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAmbWMuRmxhcmUpKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZtYy5JbGx1bWluYW50VHlwZSkpIHJldHVybiBOVUxMOwoKICAgICpuSXRlbXMgPSAxOwogICAgcmV0dXJuIF9jbXNEdXBNZW0oc2VsZiAtPkNvbnRleHRJRCwgJm1jLCBzaXplb2YoY21zSUNDTWVhc3VyZW1lbnRDb25kaXRpb25zKSk7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwp9CgoKc3RhdGljCmNtc0Jvb2wgIFR5cGVfTWVhc3VyZW1lbnRfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc0lDQ01lYXN1cmVtZW50Q29uZGl0aW9ucyogbWMgPShjbXNJQ0NNZWFzdXJlbWVudENvbmRpdGlvbnMqKSBQdHI7CgogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIG1jLT5PYnNlcnZlcikpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlWFlaTnVtYmVyKGlvLCAgICAmbWMtPkJhY2tpbmcpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgbWMtPkdlb21ldHJ5KSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIG1jLT5GbGFyZSkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBtYy0+SWxsdW1pbmFudFR5cGUpKSByZXR1cm4gRkFMU0U7CgogICAgcmV0dXJuIFRSVUU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuSXRlbXMpOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKc3RhdGljCnZvaWQqIFR5cGVfTWVhc3VyZW1lbnRfRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCAqUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICAgIHJldHVybiBfY21zRHVwTWVtKHNlbGYgLT5Db250ZXh0SUQsIFB0ciwgc2l6ZW9mKGNtc0lDQ01lYXN1cmVtZW50Q29uZGl0aW9ucykpOwoKICAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG4pOwp9CgpzdGF0aWMKdm9pZCBUeXBlX01lYXN1cmVtZW50X0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgUHRyKTsKfQoKCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFR5cGUgY21zU2lnTXVsdGlMb2NhbGl6ZWRVbmljb2RlVHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovLyAgIERvIE5PVCB0cnVzdCBTaXplT2ZUYWcgYXMgdGhlcmUgaXMgYW4gaXNzdWUgb24gdGhlIGRlZmluaXRpb24gb2YgcHJvZmlsZVNlcXVlbmNlRGVzY1RhZy4gU2VlIHRoZSBUZWNoTm90ZSBmcm9tCi8vICAgTWF4IERlcmhhayBhbmQgUm9oaXQgUGF0aWwgYWJvdXQgdGhpczogYmFzaWNhbGx5IHRoZSBzaXplIG9mIHRoZSBzdHJpbmcgdGFibGUgc2hvdWxkIGJlIGd1ZXNzZWQgYW5kIGNhbm5vdCBiZQovLyAgIHRha2VuIGZyb20gdGhlIHNpemUgb2YgdGFnIGlmIHRoaXMgdGFnIGlzIGVtYmVkZGVkIGFzIHBhcnQgb2YgYmlnZ2VyIHN0cnVjdHVyZXMgKHByb2ZpbGVTZXF1ZW5jZURlc2NUYWcsIGZvciBpbnN0YW5jZSkKLy8KCnN0YXRpYwp2b2lkICpUeXBlX01MVV9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc01MVSogbWx1OwogICAgY21zVUludDMyTnVtYmVyIENvdW50LCBSZWNMZW4sIE51bU9mV2NoYXI7CiAgICBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mSGVhZGVyOwogICAgY21zVUludDMyTnVtYmVyICBMZW4sIE9mZnNldDsKICAgIGNtc1VJbnQzMk51bWJlciAgaTsKICAgIHdjaGFyX3QqICAgICAgICAgQmxvY2s7CiAgICBjbXNVSW50MzJOdW1iZXIgIEJlZ2luT2ZUaGlzU3RyaW5nLCBFbmRPZlRoaXNTdHJpbmcsIExhcmdlc3RQb3NpdGlvbjsKCiAgICAqbkl0ZW1zID0gMDsKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZDb3VudCkpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJlJlY0xlbikpIHJldHVybiBOVUxMOwoKICAgIGlmIChSZWNMZW4gIT0gMTIpIHsKCiAgICAgICAgY21zU2lnbmFsRXJyb3Ioc2VsZi0+Q29udGV4dElELCBjbXNFUlJPUl9VTktOT1dOX0VYVEVOU0lPTiwgIm11bHRpTG9jYWxpemVkVW5pY29kZVR5cGUgb2YgbGVuICE9IDEyIGlzIG5vdCBzdXBwb3J0ZWQuIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgbWx1ID0gY21zTUxVYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgQ291bnQpOwogICAgaWYgKG1sdSA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBtbHUgLT5Vc2VkRW50cmllcyA9IENvdW50OwoKICAgIFNpemVPZkhlYWRlciA9IDEyICogQ291bnQgKyBzaXplb2YoX2Ntc1RhZ0Jhc2UpOwogICAgTGFyZ2VzdFBvc2l0aW9uID0gMDsKCiAgICBmb3IgKGk9MDsgaSA8IENvdW50OyBpKyspIHsKCiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJm1sdSAtPkVudHJpZXNbaV0uTGFuZ3VhZ2UpKSBnb3RvIEVycm9yOwogICAgICAgIGlmICghX2Ntc1JlYWRVSW50MTZOdW1iZXIoaW8sICZtbHUgLT5FbnRyaWVzW2ldLkNvdW50cnkpKSAgZ290byBFcnJvcjsKCiAgICAgICAgLy8gTm93IGRlYWwgd2l0aCBMZW4gYW5kIG9mZnNldC4KICAgICAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmTGVuKSkgZ290byBFcnJvcjsKICAgICAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmT2Zmc2V0KSkgZ290byBFcnJvcjsKCiAgICAgICAgLy8gQ2hlY2sgZm9yIG92ZXJmbG93CiAgICAgICAgaWYgKE9mZnNldCA8IChTaXplT2ZIZWFkZXIgKyA4KSkgZ290byBFcnJvcjsKCiAgICAgICAgLy8gVHJ1ZSBiZWdpbiBvZiB0aGUgc3RyaW5nCiAgICAgICAgQmVnaW5PZlRoaXNTdHJpbmcgPSBPZmZzZXQgLSBTaXplT2ZIZWFkZXIgLSA4OwoKICAgICAgICAvLyBBanVzdCB0byB3Y2hhcl90IGVsZW1lbnRzCiAgICAgICAgbWx1IC0+RW50cmllc1tpXS5MZW4gPSAoTGVuICogc2l6ZW9mKHdjaGFyX3QpKSAvIHNpemVvZihjbXNVSW50MTZOdW1iZXIpOwogICAgICAgIG1sdSAtPkVudHJpZXNbaV0uU3RyVyA9IChCZWdpbk9mVGhpc1N0cmluZyAqIHNpemVvZih3Y2hhcl90KSkgLyBzaXplb2YoY21zVUludDE2TnVtYmVyKTsKCiAgICAgICAgLy8gVG8gZ3Vlc3MgbWF4aW11bSBzaXplLCBhZGQgb2Zmc2V0ICsgbGVuCiAgICAgICAgRW5kT2ZUaGlzU3RyaW5nID0gQmVnaW5PZlRoaXNTdHJpbmcgKyBMZW47CiAgICAgICAgaWYgKEVuZE9mVGhpc1N0cmluZyA+IExhcmdlc3RQb3NpdGlvbikKICAgICAgICAgICAgTGFyZ2VzdFBvc2l0aW9uID0gRW5kT2ZUaGlzU3RyaW5nOwogICAgfQoKICAgIC8vIE5vdyByZWFkIHRoZSByZW1haW5pbmcgb2YgdGFnIGFuZCBmaWxsIGFsbCBzdHJpbmdzLiBTdWJzdHJhY3QgdGhlIGRpcmVjdG9yeQogICAgU2l6ZU9mVGFnICAgPSAoTGFyZ2VzdFBvc2l0aW9uICogc2l6ZW9mKHdjaGFyX3QpKSAvIHNpemVvZihjbXNVSW50MTZOdW1iZXIpOwogICAgaWYgKFNpemVPZlRhZyA9PSAwKQogICAgewogICAgICAgIEJsb2NrID0gTlVMTDsKICAgICAgICBOdW1PZldjaGFyID0gMDsKCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgQmxvY2sgPSAod2NoYXJfdCopIF9jbXNNYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgU2l6ZU9mVGFnKTsKICAgICAgICBpZiAoQmxvY2sgPT0gTlVMTCkgZ290byBFcnJvcjsKICAgICAgICBOdW1PZldjaGFyID0gU2l6ZU9mVGFnIC8gc2l6ZW9mKHdjaGFyX3QpOwogICAgICAgIGlmICghX2Ntc1JlYWRXQ2hhckFycmF5KGlvLCBOdW1PZldjaGFyLCBCbG9jaykpIGdvdG8gRXJyb3I7CiAgICB9CgogICAgbWx1IC0+TWVtUG9vbCAgPSBCbG9jazsKICAgIG1sdSAtPlBvb2xTaXplID0gU2l6ZU9mVGFnOwogICAgbWx1IC0+UG9vbFVzZWQgPSBTaXplT2ZUYWc7CgogICAgKm5JdGVtcyA9IDE7CiAgICByZXR1cm4gKHZvaWQqKSBtbHU7CgpFcnJvcjoKICAgIGlmIChtbHUpIGNtc01MVWZyZWUobWx1KTsKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMKY21zQm9vbCAgVHlwZV9NTFVfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc01MVSogbWx1ID0oY21zTUxVKikgUHRyOwogICAgY21zVUludDMyTnVtYmVyIEhlYWRlclNpemU7CiAgICBjbXNVSW50MzJOdW1iZXIgIExlbiwgT2Zmc2V0OwogICAgaW50IGk7CgogICAgaWYgKFB0ciA9PSBOVUxMKSB7CgogICAgICAgICAgLy8gRW1wdHkgcGxhY2Vob2xkZXIKICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIDEyKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIG1sdSAtPlVzZWRFbnRyaWVzKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIDEyKSkgcmV0dXJuIEZBTFNFOwoKICAgIEhlYWRlclNpemUgPSAxMiAqIG1sdSAtPlVzZWRFbnRyaWVzICsgc2l6ZW9mKF9jbXNUYWdCYXNlKTsKCiAgICBmb3IgKGk9MDsgaSA8IG1sdSAtPlVzZWRFbnRyaWVzOyBpKyspIHsKCiAgICAgICAgTGVuICAgID0gIG1sdSAtPkVudHJpZXNbaV0uTGVuOwogICAgICAgIE9mZnNldCA9ICBtbHUgLT5FbnRyaWVzW2ldLlN0clc7CgogICAgICAgIExlbiAgICA9IChMZW4gKiBzaXplb2YoY21zVUludDE2TnVtYmVyKSkgLyBzaXplb2Yod2NoYXJfdCk7CiAgICAgICAgT2Zmc2V0ID0gKE9mZnNldCAqIHNpemVvZihjbXNVSW50MTZOdW1iZXIpKSAvIHNpemVvZih3Y2hhcl90KSArIEhlYWRlclNpemUgKyA4OwoKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgbWx1IC0+RW50cmllc1tpXS5MYW5ndWFnZSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgbWx1IC0+RW50cmllc1tpXS5Db3VudHJ5KSkgIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgTGVuKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBPZmZzZXQpKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKCFfY21zV3JpdGVXQ2hhckFycmF5KGlvLCBtbHUgLT5Qb29sVXNlZCAvIHNpemVvZih3Y2hhcl90KSwgKHdjaGFyX3QqKSAgbWx1IC0+TWVtUG9vbCkpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKc3RhdGljCnZvaWQqIFR5cGVfTUxVX0R1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgIHJldHVybiAodm9pZCopIGNtc01MVWR1cCgoY21zTUxVKikgUHRyKTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG4pOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKc3RhdGljCnZvaWQgVHlwZV9NTFVfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQqIFB0cikKewogICAgY21zTUxVZnJlZSgoY21zTUxVKikgUHRyKTsKICAgIHJldHVybjsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBjbXNTaWdMdXQ4VHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKLy8gRGVjaWRlIHdoaWNoIExVVCB0eXBlIHRvIHVzZSBvbiB3cml0dGluZwpzdGF0aWMKY21zVGFnVHlwZVNpZ25hdHVyZSBEZWNpZGVMVVR0eXBlQTJCKGNtc0Zsb2F0NjROdW1iZXIgSUNDVmVyc2lvbiwgY29uc3Qgdm9pZCAqRGF0YSkKewogICAgY21zUGlwZWxpbmUqIEx1dCA9IChjbXNQaXBlbGluZSopIERhdGE7CgogICAgaWYgKElDQ1ZlcnNpb24gPCA0LjApIHsKICAgICAgICBpZiAoTHV0IC0+U2F2ZUFzOEJpdHMpIHJldHVybiBjbXNTaWdMdXQ4VHlwZTsKICAgICAgICByZXR1cm4gY21zU2lnTHV0MTZUeXBlOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgIHJldHVybiBjbXNTaWdMdXRBdG9CVHlwZTsKICAgIH0KfQoKc3RhdGljCmNtc1RhZ1R5cGVTaWduYXR1cmUgRGVjaWRlTFVUdHlwZUIyQShjbXNGbG9hdDY0TnVtYmVyIElDQ1ZlcnNpb24sIGNvbnN0IHZvaWQgKkRhdGEpCnsKICAgIGNtc1BpcGVsaW5lKiBMdXQgPSAoY21zUGlwZWxpbmUqKSBEYXRhOwoKICAgIGlmIChJQ0NWZXJzaW9uIDwgNC4wKSB7CiAgICAgICAgaWYgKEx1dCAtPlNhdmVBczhCaXRzKSByZXR1cm4gY21zU2lnTHV0OFR5cGU7CiAgICAgICAgcmV0dXJuIGNtc1NpZ0x1dDE2VHlwZTsKICAgIH0KICAgIGVsc2UgewogICAgICAgICByZXR1cm4gY21zU2lnTHV0QnRvQVR5cGU7CiAgICB9Cn0KCi8qClRoaXMgc3RydWN0dXJlIHJlcHJlc2VudHMgYSBjb2xvdXIgdHJhbnNmb3JtIHVzaW5nIHRhYmxlcyBvZiA4LWJpdCBwcmVjaXNpb24uClRoaXMgdHlwZSBjb250YWlucyBmb3VyIHByb2Nlc3NpbmcgZWxlbWVudHM6IGEgMyBieSAzIG1hdHJpeCAod2hpY2ggc2hhbGwgYmUKdGhlIGlkZW50aXR5IG1hdHJpeCB1bmxlc3MgdGhlIGlucHV0IGNvbG91ciBzcGFjZSBpcyBYWVopLCBhIHNldCBvZiBvbmUgZGltZW5zaW9uYWwKaW5wdXQgdGFibGVzLCBhIG11bHRpZGltZW5zaW9uYWwgbG9va3VwIHRhYmxlLCBhbmQgYSBzZXQgb2Ygb25lIGRpbWVuc2lvbmFsIG91dHB1dAp0YWJsZXMuIERhdGEgaXMgcHJvY2Vzc2VkIHVzaW5nIHRoZXNlIGVsZW1lbnRzIHZpYSB0aGUgZm9sbG93aW5nIHNlcXVlbmNlOgoobWF0cml4KSAtPiAoMWQgaW5wdXQgdGFibGVzKSAgLT4gKG11bHRpZGltZW5zaW9uYWwgbG9va3VwIHRhYmxlIC0gQ0xVVCkgLT4gKDFkIG91dHB1dCB0YWJsZXMpCgpCeXRlIFBvc2l0aW9uICAgRmllbGQgTGVuZ3RoIChieXRlcykgIENvbnRlbnQgRW5jb2RlZCBhcy4uLgo4ICAgICAgICAgICAgICAgICAgMSAgICAgICAgICBOdW1iZXIgb2YgSW5wdXQgQ2hhbm5lbHMgKGkpICAgIHVJbnQ4TnVtYmVyCjkgICAgICAgICAgICAgICAgICAxICAgICAgICAgIE51bWJlciBvZiBPdXRwdXQgQ2hhbm5lbHMgKG8pICAgdUludDhOdW1iZXIKMTAgICAgICAgICAgICAgICAgIDEgICAgICAgICAgTnVtYmVyIG9mIENMVVQgZ3JpZCBwb2ludHMgKGlkZW50aWNhbCBmb3IgZWFjaCBzaWRlKSAoZykgdUludDhOdW1iZXIKMTEgICAgICAgICAgICAgICAgIDEgICAgICAgICAgUmVzZXJ2ZWQgZm9yIHBhZGRpbmcgKGZpbGwgd2l0aCAwMGgpCgoxMi4uMTUgICAgICAgICAgICAgNCAgICAgICAgICBFbmNvZGVkIGUwMCBwYXJhbWV0ZXIgICBzMTVGaXhlZDE2TnVtYmVyCiovCgoKLy8gUmVhZCA4IGJpdCB0YWJsZXMgYXMgZ2FtbWEgZnVuY3Rpb25zCnN0YXRpYwpjbXNCb29sICBSZWFkOGJpdFRhYmxlcyhjbXNDb250ZXh0IENvbnRleHRJRCwgY21zSU9IQU5ETEVSKiBpbywgY21zUGlwZWxpbmUqIGx1dCwgaW50IG5DaGFubmVscykKewogICAgY21zVUludDhOdW1iZXIqIFRlbXAgPSBOVUxMOwogICAgaW50IGksIGo7CiAgICBjbXNUb25lQ3VydmUqIFRhYmxlc1tjbXNNQVhDSEFOTkVMU107CgogICAgaWYgKG5DaGFubmVscyA+IGNtc01BWENIQU5ORUxTKSByZXR1cm4gRkFMU0U7CiAgICBpZiAobkNoYW5uZWxzIDw9IDApIHJldHVybiBGQUxTRTsKCiAgICBtZW1zZXQoVGFibGVzLCAwLCBzaXplb2YoVGFibGVzKSk7CgogICAgVGVtcCA9IChjbXNVSW50OE51bWJlciopIF9jbXNNYWxsb2MoQ29udGV4dElELCAyNTYpOwogICAgaWYgKFRlbXAgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAoaT0wOyBpIDwgbkNoYW5uZWxzOyBpKyspIHsKICAgICAgICBUYWJsZXNbaV0gPSBjbXNCdWlsZFRhYnVsYXRlZFRvbmVDdXJ2ZTE2KENvbnRleHRJRCwgMjU2LCBOVUxMKTsKICAgICAgICBpZiAoVGFibGVzW2ldID09IE5VTEwpIGdvdG8gRXJyb3I7CiAgICB9CgogICAgZm9yIChpPTA7IGkgPCBuQ2hhbm5lbHM7IGkrKykgewoKICAgICAgICBpZiAoaW8gLT5SZWFkKGlvLCBUZW1wLCAyNTYsIDEpICE9IDEpIGdvdG8gRXJyb3I7CgogICAgICAgIGZvciAoaj0wOyBqIDwgMjU2OyBqKyspCiAgICAgICAgICAgIFRhYmxlc1tpXS0+VGFibGUxNltqXSA9IChjbXNVSW50MTZOdW1iZXIpIEZST01fOF9UT18xNihUZW1wW2pdKTsKICAgIH0KCiAgICBfY21zRnJlZShDb250ZXh0SUQsIFRlbXApOwogICAgVGVtcCA9IE5VTEw7CgogICAgaWYgKCFjbXNQaXBlbGluZUluc2VydFN0YWdlKGx1dCwgY21zQVRfRU5ELCBjbXNTdGFnZUFsbG9jVG9uZUN1cnZlcyhDb250ZXh0SUQsIG5DaGFubmVscywgVGFibGVzKSkpCiAgICAgICAgZ290byBFcnJvcjsKCiAgICBmb3IgKGk9MDsgaSA8IG5DaGFubmVsczsgaSsrKQogICAgICAgIGNtc0ZyZWVUb25lQ3VydmUoVGFibGVzW2ldKTsKCiAgICByZXR1cm4gVFJVRTsKCkVycm9yOgogICAgZm9yIChpPTA7IGkgPCBuQ2hhbm5lbHM7IGkrKykgewogICAgICAgIGlmIChUYWJsZXNbaV0pIGNtc0ZyZWVUb25lQ3VydmUoVGFibGVzW2ldKTsKICAgIH0KCiAgICBpZiAoVGVtcCkgX2Ntc0ZyZWUoQ29udGV4dElELCBUZW1wKTsKICAgIHJldHVybiBGQUxTRTsKfQoKCnN0YXRpYwpjbXNCb29sIFdyaXRlOGJpdFRhYmxlcyhjbXNDb250ZXh0IENvbnRleHRJRCwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyIG4sIF9jbXNTdGFnZVRvbmVDdXJ2ZXNEYXRhKiBUYWJsZXMpCnsKICAgIGludCBqOwogICAgY21zVUludDMyTnVtYmVyIGk7CiAgICBjbXNVSW50OE51bWJlciB2YWw7CgogICAgZm9yIChpPTA7IGkgPCBuOyBpKyspIHsKCiAgICAgICAgaWYgKFRhYmxlcykgewoKICAgICAgICAgICAgLy8gVXN1YWwgY2FzZSBvZiBpZGVudGl0eSBjdXJ2ZXMKICAgICAgICAgICAgaWYgKChUYWJsZXMgLT5UaGVDdXJ2ZXNbaV0tPm5FbnRyaWVzID09IDIpICYmIAogICAgICAgICAgICAgICAgKFRhYmxlcy0+VGhlQ3VydmVzW2ldLT5UYWJsZTE2WzBdID09IDApICYmIAogICAgICAgICAgICAgICAgKFRhYmxlcy0+VGhlQ3VydmVzW2ldLT5UYWJsZTE2WzFdID09IDY1NTM1KSkgewoKICAgICAgICAgICAgICAgICAgICBmb3IgKGo9MDsgaiA8IDI1NjsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDhOdW1iZXIoaW8sIChjbXNVSW50OE51bWJlcikgaikpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIGlmIChUYWJsZXMgLT5UaGVDdXJ2ZXNbaV0tPm5FbnRyaWVzICE9IDI1NikgewogICAgICAgICAgICAgICAgICAgIGNtc1NpZ25hbEVycm9yKENvbnRleHRJRCwgY21zRVJST1JfUkFOR0UsICJMVVQ4IG5lZWRzIDI1NiBlbnRyaWVzIG9uIHByZWxpbmVhcml6YXRpb24iKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGZvciAoaj0wOyBqIDwgMjU2OyBqKyspIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChUYWJsZXMgIT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IChjbXNVSW50OE51bWJlcikgRlJPTV8xNl9UT184KFRhYmxlcy0+VGhlQ3VydmVzW2ldLT5UYWJsZTE2W2pdKTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gKGNtc1VJbnQ4TnVtYmVyKSBqOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50OE51bWJlcihpbywgdmFsKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8vIENoZWNrIG92ZXJmbG93CnN0YXRpYwpjbXNVSW50MzJOdW1iZXIgdWlwb3coY21zVUludDMyTnVtYmVyIG4sIGNtc1VJbnQzMk51bWJlciBhLCBjbXNVSW50MzJOdW1iZXIgYikKewogICAgY21zVUludDMyTnVtYmVyIHJ2ID0gMSwgcmM7CgogICAgaWYgKGEgPT0gMCkgcmV0dXJuIDA7CiAgICBpZiAobiA9PSAwKSByZXR1cm4gMDsKCiAgICBmb3IgKDsgYiA+IDA7IGItLSkgewoKICAgICAgICBydiAqPSBhOwoKICAgICAgICAvLyBDaGVjayBmb3Igb3ZlcmZsb3cKICAgICAgICBpZiAocnYgPiBVSU5UX01BWCAvIGEpIHJldHVybiAoY21zVUludDMyTnVtYmVyKSAtMTsKCiAgICB9CgogICAgcmMgPSBydiAqIG47CgogICAgaWYgKHJ2ICE9IHJjIC8gbikgcmV0dXJuIChjbXNVSW50MzJOdW1iZXIpIC0xOwogICAgcmV0dXJuIHJjOwp9CgoKLy8gVGhhdCB3aWxsIGNyZWF0ZSBhIE1QRSBMVVQgd2l0aCBNYXRyaXgsIHByZSB0YWJsZXMsIENMVVQgYW5kIHBvc3QgdGFibGVzLgovLyA4IGJpdCBsdXQgbWF5IGJlIHNjYWxlZCBlYXNlbHkgdG8gdjQgUENTLCBidXQgd2UgbmVlZCBhbHNvIHRvIHByb3Blcmx5IGFkanVzdAovLyBQQ1Mgb24gQlRvQXh4IHRhZ3MgYW5kIEF0b0IgaWYgYWJzdHJhY3QuIFdlIG5lZWQgdG8gZml4IGlucHV0IGRpcmVjdGlvbi4KCnN0YXRpYwp2b2lkICpUeXBlX0xVVDhfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNVSW50OE51bWJlciBJbnB1dENoYW5uZWxzLCBPdXRwdXRDaGFubmVscywgQ0xVVHBvaW50czsKICAgIGNtc1VJbnQ4TnVtYmVyKiBUZW1wID0gTlVMTDsKICAgIGNtc1BpcGVsaW5lKiBOZXdMVVQgPSBOVUxMOwogICAgY21zVUludDMyTnVtYmVyIG5UYWJTaXplLCBpOwogICAgY21zRmxvYXQ2NE51bWJlciBNYXRyaXhbMyozXTsKCiAgICAqbkl0ZW1zID0gMDsKCiAgICBpZiAoIV9jbXNSZWFkVUludDhOdW1iZXIoaW8sICZJbnB1dENoYW5uZWxzKSkgZ290byBFcnJvcjsKICAgIGlmICghX2Ntc1JlYWRVSW50OE51bWJlcihpbywgJk91dHB1dENoYW5uZWxzKSkgZ290byBFcnJvcjsKICAgIGlmICghX2Ntc1JlYWRVSW50OE51bWJlcihpbywgJkNMVVRwb2ludHMpKSBnb3RvIEVycm9yOwoKICAgICBpZiAoQ0xVVHBvaW50cyA9PSAxKSBnb3RvIEVycm9yOyAvLyBJbXBvc3NpYmxlIHZhbHVlLCAwIGZvciBubyBDTFVUIGFuZCB0aGVuIDIgYXQgbGVhc3QKCiAgICAvLyBQYWRkaW5nCiAgICBpZiAoIV9jbXNSZWFkVUludDhOdW1iZXIoaW8sIE5VTEwpKSBnb3RvIEVycm9yOwoKICAgIC8vIERvIHNvbWUgY2hlY2tpbmcKICAgIGlmIChJbnB1dENoYW5uZWxzID4gY21zTUFYQ0hBTk5FTFMpICBnb3RvIEVycm9yOwogICAgaWYgKE91dHB1dENoYW5uZWxzID4gY21zTUFYQ0hBTk5FTFMpIGdvdG8gRXJyb3I7CgogICAvLyBBbGxvY2F0ZXMgYW4gZW1wdHkgUGlwZWxpbmUKICAgIE5ld0xVVCA9IGNtc1BpcGVsaW5lQWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgSW5wdXRDaGFubmVscywgT3V0cHV0Q2hhbm5lbHMpOwogICAgaWYgKE5ld0xVVCA9PSBOVUxMKSBnb3RvIEVycm9yOwoKICAgIC8vIFJlYWQgdGhlIE1hdHJpeAogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgICZNYXRyaXhbMF0pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgICZNYXRyaXhbMV0pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgICZNYXRyaXhbMl0pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgICZNYXRyaXhbM10pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgICZNYXRyaXhbNF0pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgICZNYXRyaXhbNV0pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgICZNYXRyaXhbNl0pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgICZNYXRyaXhbN10pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgICZNYXRyaXhbOF0pKSBnb3RvIEVycm9yOwoKCiAgICAvLyBPbmx5IG9wZXJhdGVzIGlmIG5vdCBpZGVudGl0eS4uLgogICAgaWYgKChJbnB1dENoYW5uZWxzID09IDMpICYmICFfY21zTUFUM2lzSWRlbnRpdHkoKGNtc01BVDMqKSBNYXRyaXgpKSB7CgogICAgICAgIGlmICghY21zUGlwZWxpbmVJbnNlcnRTdGFnZShOZXdMVVQsIGNtc0FUX0JFR0lOLCBjbXNTdGFnZUFsbG9jTWF0cml4KHNlbGYgLT5Db250ZXh0SUQsIDMsIDMsIE1hdHJpeCwgTlVMTCkpKQogICAgICAgICAgICBnb3RvIEVycm9yOwogICAgfQoKICAgIC8vIEdldCBpbnB1dCB0YWJsZXMKICAgIGlmICghUmVhZDhiaXRUYWJsZXMoc2VsZiAtPkNvbnRleHRJRCwgaW8sICBOZXdMVVQsIElucHV0Q2hhbm5lbHMpKSBnb3RvIEVycm9yOwoKICAgIC8vIEdldCAzRCBDTFVULiBDaGVjayB0aGUgb3ZlcmZsb3cuLi4uCiAgICBuVGFiU2l6ZSA9IHVpcG93KE91dHB1dENoYW5uZWxzLCBDTFVUcG9pbnRzLCBJbnB1dENoYW5uZWxzKTsKICAgIGlmIChuVGFiU2l6ZSA9PSAoY21zVUludDMyTnVtYmVyKSAtMSkgZ290byBFcnJvcjsKICAgIGlmIChuVGFiU2l6ZSA+IDApIHsKCiAgICAgICAgY21zVUludDE2TnVtYmVyICpQdHJXLCAqVDsKICAgICAgIAogICAgICAgIFB0clcgPSBUICA9IChjbXNVSW50MTZOdW1iZXIqKSBfY21zQ2FsbG9jKHNlbGYgLT5Db250ZXh0SUQsIG5UYWJTaXplLCBzaXplb2YoY21zVUludDE2TnVtYmVyKSk7CiAgICAgICAgaWYgKFQgID09IE5VTEwpIGdvdG8gRXJyb3I7CgogICAgICAgIFRlbXAgPSAoY21zVUludDhOdW1iZXIqKSBfY21zTWFsbG9jKHNlbGYgLT5Db250ZXh0SUQsIG5UYWJTaXplKTsKICAgICAgICBpZiAoVGVtcCA9PSBOVUxMKSB7CiAgICAgICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFQpOwogICAgICAgICAgICBnb3RvIEVycm9yOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlvIC0+UmVhZChpbywgVGVtcCwgblRhYlNpemUsIDEpICE9IDEpIHsKICAgICAgICAgICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgVCk7CiAgICAgICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFRlbXApOwogICAgICAgICAgICBnb3RvIEVycm9yOwogICAgICAgIH0KCiAgICAgICAgZm9yIChpID0gMDsgaSA8IG5UYWJTaXplOyBpKyspIHsKCiAgICAgICAgICAgICpQdHJXKysgPSBGUk9NXzhfVE9fMTYoVGVtcFtpXSk7CiAgICAgICAgfQogICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFRlbXApOwogICAgICAgIFRlbXAgPSBOVUxMOwoKICAgICAgICBpZiAoIWNtc1BpcGVsaW5lSW5zZXJ0U3RhZ2UoTmV3TFVULCBjbXNBVF9FTkQsIGNtc1N0YWdlQWxsb2NDTHV0MTZiaXQoc2VsZiAtPkNvbnRleHRJRCwgQ0xVVHBvaW50cywgSW5wdXRDaGFubmVscywgT3V0cHV0Q2hhbm5lbHMsIFQpKSkKICAgICAgICAgICAgZ290byBFcnJvcjsKICAgICAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBUKTsKICAgIH0KCgogICAgLy8gR2V0IG91dHB1dCB0YWJsZXMKICAgIGlmICghUmVhZDhiaXRUYWJsZXMoc2VsZiAtPkNvbnRleHRJRCwgaW8sICBOZXdMVVQsIE91dHB1dENoYW5uZWxzKSkgZ290byBFcnJvcjsKCiAgICAqbkl0ZW1zID0gMTsKICAgIHJldHVybiBOZXdMVVQ7CgpFcnJvcjoKICAgIGlmIChOZXdMVVQgIT0gTlVMTCkgY21zUGlwZWxpbmVGcmVlKE5ld0xVVCk7CiAgICByZXR1cm4gTlVMTDsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKFNpemVPZlRhZyk7Cn0KCi8vIFdlIG9ubHkgYWxsb3cgYSBzcGVjaWZpYyBNUEUgc3RydWN0dXJlOiBNYXRyaXggcGx1cyBwcmVsaW4sIHBsdXMgY2x1dCwgcGx1cyBwb3N0LWxpbi4Kc3RhdGljCmNtc0Jvb2wgIFR5cGVfTFVUOF9Xcml0ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIHZvaWQqIFB0ciwgY21zVUludDMyTnVtYmVyIG5JdGVtcykKewogICAgY21zVUludDMyTnVtYmVyIGosIG5UYWJTaXplOwogICAgY21zVUludDhOdW1iZXIgIHZhbDsKICAgIGNtc1BpcGVsaW5lKiBOZXdMVVQgPSAoY21zUGlwZWxpbmUqKSBQdHI7CiAgICBjbXNTdGFnZSogbXBlOwogICAgX2Ntc1N0YWdlVG9uZUN1cnZlc0RhdGEqIFByZU1QRSA9IE5VTEwsICpQb3N0TVBFID0gTlVMTDsKICAgIF9jbXNTdGFnZU1hdHJpeERhdGEqIE1hdE1QRSA9IE5VTEw7CiAgICBfY21zU3RhZ2VDTHV0RGF0YSogY2x1dCA9IE5VTEw7CiAgICBpbnQgY2x1dFBvaW50czsKCiAgICAvLyBEaXNhc3NlbWJsZSB0aGUgTFVUIGludG8gY29tcG9uZW50cy4KICAgIG1wZSA9IE5ld0xVVCAtPiBFbGVtZW50czsKICAgIGlmIChtcGUgLT5UeXBlID09IGNtc1NpZ01hdHJpeEVsZW1UeXBlKSB7CgogICAgICAgIE1hdE1QRSA9IChfY21zU3RhZ2VNYXRyaXhEYXRhKikgbXBlIC0+RGF0YTsKICAgICAgICBtcGUgPSBtcGUgLT4gTmV4dDsKICAgIH0KCiAgICBpZiAobXBlICE9IE5VTEwgJiYgbXBlIC0+VHlwZSA9PSBjbXNTaWdDdXJ2ZVNldEVsZW1UeXBlKSB7CiAgICAgICAgUHJlTVBFID0gKF9jbXNTdGFnZVRvbmVDdXJ2ZXNEYXRhKikgbXBlIC0+RGF0YTsKICAgICAgICBtcGUgPSBtcGUgLT4gTmV4dDsKICAgIH0KCiAgICBpZiAobXBlICE9IE5VTEwgJiYgbXBlIC0+VHlwZSA9PSBjbXNTaWdDTHV0RWxlbVR5cGUpIHsKICAgICAgICBjbHV0ICA9IChfY21zU3RhZ2VDTHV0RGF0YSopIG1wZSAtPiBEYXRhOwogICAgICAgIG1wZSA9IG1wZSAtPk5leHQ7CiAgICB9CgogICAgaWYgKG1wZSAhPSBOVUxMICYmIG1wZSAtPlR5cGUgPT0gY21zU2lnQ3VydmVTZXRFbGVtVHlwZSkgewogICAgICAgIFBvc3RNUEUgPSAoX2Ntc1N0YWdlVG9uZUN1cnZlc0RhdGEqKSBtcGUgLT5EYXRhOwogICAgICAgIG1wZSA9IG1wZSAtPiBOZXh0OwogICAgfQoKICAgIC8vIFRoYXQgc2hvdWxkIGJlIGFsbAogICAgaWYgKG1wZSAhPSBOVUxMKSB7CiAgICAgICAgY21zU2lnbmFsRXJyb3IobXBlLT5Db250ZXh0SUQsIGNtc0VSUk9SX1VOS05PV05fRVhURU5TSU9OLCAiTFVUIGlzIG5vdCBzdWl0YWJsZSB0byBiZSBzYXZlZCBhcyBMVVQ4Iik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKCiAgICBpZiAoY2x1dCA9PSBOVUxMKQogICAgICAgIGNsdXRQb2ludHMgPSAwOwogICAgZWxzZQogICAgICAgIGNsdXRQb2ludHMgICAgPSBjbHV0LT5QYXJhbXMtPm5TYW1wbGVzWzBdOwoKICAgIGlmICghX2Ntc1dyaXRlVUludDhOdW1iZXIoaW8sIChjbXNVSW50OE51bWJlcikgTmV3TFVUIC0+SW5wdXRDaGFubmVscykpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDhOdW1iZXIoaW8sIChjbXNVSW50OE51bWJlcikgTmV3TFVUIC0+T3V0cHV0Q2hhbm5lbHMpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQ4TnVtYmVyKGlvLCAoY21zVUludDhOdW1iZXIpIGNsdXRQb2ludHMpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQ4TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOyAvLyBQYWRkaW5nCgoKICAgIGlmIChNYXRNUEUgIT0gTlVMTCkgewoKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgTWF0TVBFIC0+IERvdWJsZVswXSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgTWF0TVBFIC0+IERvdWJsZVsxXSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgTWF0TVBFIC0+IERvdWJsZVsyXSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgTWF0TVBFIC0+IERvdWJsZVszXSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgTWF0TVBFIC0+IERvdWJsZVs0XSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgTWF0TVBFIC0+IERvdWJsZVs1XSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgTWF0TVBFIC0+IERvdWJsZVs2XSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgTWF0TVBFIC0+IERvdWJsZVs3XSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgTWF0TVBFIC0+IERvdWJsZVs4XSkpIHJldHVybiBGQUxTRTsKCiAgICB9CiAgICBlbHNlIHsKCiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIDEpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIDEpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIDEpKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgLy8gVGhlIHByZWxpbmVhcml6YXRpb24gdGFibGUKICAgIGlmICghV3JpdGU4Yml0VGFibGVzKHNlbGYgLT5Db250ZXh0SUQsIGlvLCBOZXdMVVQgLT5JbnB1dENoYW5uZWxzLCBQcmVNUEUpKSByZXR1cm4gRkFMU0U7CgogICAgblRhYlNpemUgPSB1aXBvdyhOZXdMVVQtPk91dHB1dENoYW5uZWxzLCBjbHV0UG9pbnRzLCBOZXdMVVQgLT5JbnB1dENoYW5uZWxzKTsKICAgIGlmIChuVGFiU2l6ZSA9PSAoY21zVUludDMyTnVtYmVyKSAtMSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKG5UYWJTaXplID4gMCkgewoKICAgICAgICAvLyBUaGUgM0QgQ0xVVC4KICAgICAgICBpZiAoY2x1dCAhPSBOVUxMKSB7CgogICAgICAgICAgICBmb3IgKGo9MDsgaiA8IG5UYWJTaXplOyBqKyspIHsKCiAgICAgICAgICAgICAgICB2YWwgPSAoY21zVUludDhOdW1iZXIpIEZST01fMTZfVE9fOChjbHV0IC0+VGFiLlRbal0pOwogICAgICAgICAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50OE51bWJlcihpbywgdmFsKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIFRoZSBwb3N0bGluZWFyaXphdGlvbiB0YWJsZQogICAgaWYgKCFXcml0ZThiaXRUYWJsZXMoc2VsZiAtPkNvbnRleHRJRCwgaW8sIE5ld0xVVCAtPk91dHB1dENoYW5uZWxzLCBQb3N0TVBFKSkgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBUUlVFOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKfQoKCnN0YXRpYwp2b2lkKiBUeXBlX0xVVDhfRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCAqUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICAgcmV0dXJuICh2b2lkKikgY21zUGlwZWxpbmVEdXAoKGNtc1BpcGVsaW5lKikgUHRyKTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG4pOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKc3RhdGljCnZvaWQgVHlwZV9MVVQ4X0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIGNtc1BpcGVsaW5lRnJlZSgoY21zUGlwZWxpbmUqKSBQdHIpOwogICAgcmV0dXJuOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFR5cGUgY21zU2lnTHV0MTZUeXBlCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgovLyBSZWFkIDE2IGJpdCB0YWJsZXMgYXMgZ2FtbWEgZnVuY3Rpb25zCnN0YXRpYwpjbXNCb29sICBSZWFkMTZiaXRUYWJsZXMoY21zQ29udGV4dCBDb250ZXh0SUQsIGNtc0lPSEFORExFUiogaW8sIGNtc1BpcGVsaW5lKiBsdXQsIGludCBuQ2hhbm5lbHMsIGludCBuRW50cmllcykKewogICAgaW50IGk7CiAgICBjbXNUb25lQ3VydmUqIFRhYmxlc1tjbXNNQVhDSEFOTkVMU107CgogICAgLy8gTWF5YmUgYW4gZW1wdHkgdGFibGU/ICh0aGlzIGlzIGEgbGNtcyBleHRlbnNpb24pCiAgICBpZiAobkVudHJpZXMgPD0gMCkgcmV0dXJuIFRSVUU7CgogICAgLy8gQ2hlY2sgZm9yIG1hbGljaW91cyBwcm9maWxlcwogICAgaWYgKG5FbnRyaWVzIDwgMikgcmV0dXJuIEZBTFNFOwogICAgaWYgKG5DaGFubmVscyA+IGNtc01BWENIQU5ORUxTKSByZXR1cm4gRkFMU0U7CgogICAgLy8gSW5pdCB0YWJsZSB0byB6ZXJvCiAgICBtZW1zZXQoVGFibGVzLCAwLCBzaXplb2YoVGFibGVzKSk7CgogICAgZm9yIChpPTA7IGkgPCBuQ2hhbm5lbHM7IGkrKykgewoKICAgICAgICBUYWJsZXNbaV0gPSBjbXNCdWlsZFRhYnVsYXRlZFRvbmVDdXJ2ZTE2KENvbnRleHRJRCwgbkVudHJpZXMsIE5VTEwpOwogICAgICAgIGlmIChUYWJsZXNbaV0gPT0gTlVMTCkgZ290byBFcnJvcjsKCiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNkFycmF5KGlvLCBuRW50cmllcywgVGFibGVzW2ldLT5UYWJsZTE2KSkgZ290byBFcnJvcjsKICAgIH0KCgogICAgLy8gQWRkIHRoZSB0YWJsZSAod2hpY2ggbWF5IGNlcnRhaW5seSBiZSBhbiBpZGVudGl0eSwgYnV0IHRoaXMgaXMgdXAgdG8gdGhlIG9wdGltaXplciwgbm90IHRoZSByZWFkaW5nIGNvZGUpCiAgICBpZiAoIWNtc1BpcGVsaW5lSW5zZXJ0U3RhZ2UobHV0LCBjbXNBVF9FTkQsIGNtc1N0YWdlQWxsb2NUb25lQ3VydmVzKENvbnRleHRJRCwgbkNoYW5uZWxzLCBUYWJsZXMpKSkKICAgICAgICBnb3RvIEVycm9yOwoKICAgIGZvciAoaT0wOyBpIDwgbkNoYW5uZWxzOyBpKyspCiAgICAgICAgY21zRnJlZVRvbmVDdXJ2ZShUYWJsZXNbaV0pOwoKICAgIHJldHVybiBUUlVFOwoKRXJyb3I6CiAgICBmb3IgKGk9MDsgaSA8IG5DaGFubmVsczsgaSsrKSB7CiAgICAgICAgaWYgKFRhYmxlc1tpXSkgY21zRnJlZVRvbmVDdXJ2ZShUYWJsZXNbaV0pOwogICAgfQoKICAgIHJldHVybiBGQUxTRTsKfQoKc3RhdGljCmNtc0Jvb2wgV3JpdGUxNmJpdFRhYmxlcyhjbXNDb250ZXh0IENvbnRleHRJRCwgY21zSU9IQU5ETEVSKiBpbywgX2Ntc1N0YWdlVG9uZUN1cnZlc0RhdGEqIFRhYmxlcykKewogICAgaW50IGo7CiAgICBjbXNVSW50MzJOdW1iZXIgaTsKICAgIGNtc1VJbnQxNk51bWJlciB2YWw7CiAgICBpbnQgbkVudHJpZXM7CgogICAgX2Ntc0Fzc2VydChUYWJsZXMgIT0gTlVMTCk7CgogICAgbkVudHJpZXMgPSBUYWJsZXMtPlRoZUN1cnZlc1swXS0+bkVudHJpZXM7CgogICAgZm9yIChpPTA7IGkgPCBUYWJsZXMgLT5uQ3VydmVzOyBpKyspIHsKCiAgICAgICAgZm9yIChqPTA7IGogPCBuRW50cmllczsgaisrKSB7CgogICAgICAgICAgICB2YWwgPSBUYWJsZXMtPlRoZUN1cnZlc1tpXS0+VGFibGUxNltqXTsgICAgICAgIAogICAgICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgdmFsKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBUUlVFOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoQ29udGV4dElEKTsKfQoKc3RhdGljCnZvaWQgKlR5cGVfTFVUMTZfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNVSW50OE51bWJlciBJbnB1dENoYW5uZWxzLCBPdXRwdXRDaGFubmVscywgQ0xVVHBvaW50czsKICAgIGNtc1BpcGVsaW5lKiBOZXdMVVQgPSBOVUxMOwogICAgY21zVUludDMyTnVtYmVyIG5UYWJTaXplOwogICAgY21zRmxvYXQ2NE51bWJlciBNYXRyaXhbMyozXTsKICAgIGNtc1VJbnQxNk51bWJlciBJbnB1dEVudHJpZXMsIE91dHB1dEVudHJpZXM7CgogICAgKm5JdGVtcyA9IDA7CgogICAgaWYgKCFfY21zUmVhZFVJbnQ4TnVtYmVyKGlvLCAmSW5wdXRDaGFubmVscykpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZFVJbnQ4TnVtYmVyKGlvLCAmT3V0cHV0Q2hhbm5lbHMpKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50OE51bWJlcihpbywgJkNMVVRwb2ludHMpKSByZXR1cm4gTlVMTDsgICAvLyAyNTUgbWF4aW11bQoKICAgIC8vIFBhZGRpbmcKICAgIGlmICghX2Ntc1JlYWRVSW50OE51bWJlcihpbywgTlVMTCkpIHJldHVybiBOVUxMOwoKICAgIC8vIERvIHNvbWUgY2hlY2tpbmcKICAgIGlmIChJbnB1dENoYW5uZWxzID4gY21zTUFYQ0hBTk5FTFMpICBnb3RvIEVycm9yOwogICAgaWYgKE91dHB1dENoYW5uZWxzID4gY21zTUFYQ0hBTk5FTFMpIGdvdG8gRXJyb3I7CgogICAgLy8gQWxsb2NhdGVzIGFuIGVtcHR5IExVVAogICAgTmV3TFVUID0gY21zUGlwZWxpbmVBbGxvYyhzZWxmIC0+Q29udGV4dElELCBJbnB1dENoYW5uZWxzLCBPdXRwdXRDaGFubmVscyk7CiAgICBpZiAoTmV3TFVUID09IE5VTEwpIGdvdG8gRXJyb3I7CgogICAgLy8gUmVhZCB0aGUgTWF0cml4CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAgJk1hdHJpeFswXSkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAgJk1hdHJpeFsxXSkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAgJk1hdHJpeFsyXSkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAgJk1hdHJpeFszXSkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAgJk1hdHJpeFs0XSkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAgJk1hdHJpeFs1XSkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAgJk1hdHJpeFs2XSkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAgJk1hdHJpeFs3XSkpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAgJk1hdHJpeFs4XSkpIGdvdG8gRXJyb3I7CgoKICAgIC8vIE9ubHkgb3BlcmF0ZXMgb24gMyBjaGFubmVscwogICAgaWYgKChJbnB1dENoYW5uZWxzID09IDMpICYmICFfY21zTUFUM2lzSWRlbnRpdHkoKGNtc01BVDMqKSBNYXRyaXgpKSB7CgogICAgICAgIGlmICghY21zUGlwZWxpbmVJbnNlcnRTdGFnZShOZXdMVVQsIGNtc0FUX0VORCwgY21zU3RhZ2VBbGxvY01hdHJpeChzZWxmIC0+Q29udGV4dElELCAzLCAzLCBNYXRyaXgsIE5VTEwpKSkKICAgICAgICAgICAgZ290byBFcnJvcjsKICAgIH0KCiAgICBpZiAoIV9jbXNSZWFkVUludDE2TnVtYmVyKGlvLCAmSW5wdXRFbnRyaWVzKSkgZ290byBFcnJvcjsKICAgIGlmICghX2Ntc1JlYWRVSW50MTZOdW1iZXIoaW8sICZPdXRwdXRFbnRyaWVzKSkgZ290byBFcnJvcjsKCiAgICBpZiAoSW5wdXRFbnRyaWVzID4gMHg3RkZGIHx8IE91dHB1dEVudHJpZXMgPiAweDdGRkYpIGdvdG8gRXJyb3I7CiAgICBpZiAoQ0xVVHBvaW50cyA9PSAxKSBnb3RvIEVycm9yOyAvLyBJbXBvc3NpYmxlIHZhbHVlLCAwIGZvciBubyBDTFVUIGFuZCB0aGVuIDIgYXQgbGVhc3QKCiAgICAvLyBHZXQgaW5wdXQgdGFibGVzCiAgICBpZiAoIVJlYWQxNmJpdFRhYmxlcyhzZWxmIC0+Q29udGV4dElELCBpbywgIE5ld0xVVCwgSW5wdXRDaGFubmVscywgSW5wdXRFbnRyaWVzKSkgZ290byBFcnJvcjsKCiAgICAvLyBHZXQgM0QgQ0xVVAogICAgblRhYlNpemUgPSB1aXBvdyhPdXRwdXRDaGFubmVscywgQ0xVVHBvaW50cywgSW5wdXRDaGFubmVscyk7CiAgICBpZiAoblRhYlNpemUgPT0gKGNtc1VJbnQzMk51bWJlcikgLTEpIGdvdG8gRXJyb3I7CiAgICBpZiAoblRhYlNpemUgPiAwKSB7CgogICAgICAgIGNtc1VJbnQxNk51bWJlciAqVDsKCiAgICAgICAgVCAgPSAoY21zVUludDE2TnVtYmVyKikgX2Ntc0NhbGxvYyhzZWxmIC0+Q29udGV4dElELCBuVGFiU2l6ZSwgc2l6ZW9mKGNtc1VJbnQxNk51bWJlcikpOwogICAgICAgIGlmIChUICA9PSBOVUxMKSBnb3RvIEVycm9yOwoKICAgICAgICBpZiAoIV9jbXNSZWFkVUludDE2QXJyYXkoaW8sIG5UYWJTaXplLCBUKSkgewogICAgICAgICAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBUKTsKICAgICAgICAgICAgZ290byBFcnJvcjsKICAgICAgICB9CgogICAgICAgIGlmICghY21zUGlwZWxpbmVJbnNlcnRTdGFnZShOZXdMVVQsIGNtc0FUX0VORCwgY21zU3RhZ2VBbGxvY0NMdXQxNmJpdChzZWxmIC0+Q29udGV4dElELCBDTFVUcG9pbnRzLCBJbnB1dENoYW5uZWxzLCBPdXRwdXRDaGFubmVscywgVCkpKSB7CiAgICAgICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFQpOwogICAgICAgICAgICBnb3RvIEVycm9yOwogICAgICAgIH0KICAgICAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBUKTsKICAgIH0KCgogICAgLy8gR2V0IG91dHB1dCB0YWJsZXMKICAgIGlmICghUmVhZDE2Yml0VGFibGVzKHNlbGYgLT5Db250ZXh0SUQsIGlvLCAgTmV3TFVULCBPdXRwdXRDaGFubmVscywgT3V0cHV0RW50cmllcykpIGdvdG8gRXJyb3I7CgogICAgKm5JdGVtcyA9IDE7CiAgICByZXR1cm4gTmV3TFVUOwoKRXJyb3I6CiAgICBpZiAoTmV3TFVUICE9IE5VTEwpIGNtc1BpcGVsaW5lRnJlZShOZXdMVVQpOwogICAgcmV0dXJuIE5VTEw7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwp9CgovLyBXZSBvbmx5IGFsbG93IHNvbWUgc3BlY2lmaWMgTVBFIHN0cnVjdHVyZXM6IE1hdHJpeCBwbHVzIHByZWxpbiwgcGx1cyBjbHV0LCBwbHVzIHBvc3QtbGluLgovLyBTb21lIGVtcHR5IGRlZmF1bHRzIGFyZSBjcmVhdGVkIGZvciBtaXNzaW5nIHBhcnRzCgpzdGF0aWMKY21zQm9vbCAgVHlwZV9MVVQxNl9Xcml0ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIHZvaWQqIFB0ciwgY21zVUludDMyTnVtYmVyIG5JdGVtcykKewogICAgY21zVUludDMyTnVtYmVyIG5UYWJTaXplOwogICAgY21zUGlwZWxpbmUqIE5ld0xVVCA9IChjbXNQaXBlbGluZSopIFB0cjsKICAgIGNtc1N0YWdlKiBtcGU7CiAgICBfY21zU3RhZ2VUb25lQ3VydmVzRGF0YSogUHJlTVBFID0gTlVMTCwgKlBvc3RNUEUgPSBOVUxMOwogICAgX2Ntc1N0YWdlTWF0cml4RGF0YSogTWF0TVBFID0gTlVMTDsKICAgIF9jbXNTdGFnZUNMdXREYXRhKiBjbHV0ID0gTlVMTDsKICAgIGludCBpLCBJbnB1dENoYW5uZWxzLCBPdXRwdXRDaGFubmVscywgY2x1dFBvaW50czsKCiAgICAvLyBEaXNhc3NlbWJsZSB0aGUgTFVUIGludG8gY29tcG9uZW50cy4KICAgIG1wZSA9IE5ld0xVVCAtPiBFbGVtZW50czsKICAgIGlmIChtcGUgIT0gTlVMTCAmJiBtcGUgLT5UeXBlID09IGNtc1NpZ01hdHJpeEVsZW1UeXBlKSB7CgogICAgICAgIE1hdE1QRSA9IChfY21zU3RhZ2VNYXRyaXhEYXRhKikgbXBlIC0+RGF0YTsKICAgICAgICBtcGUgPSBtcGUgLT4gTmV4dDsKICAgIH0KCgogICAgaWYgKG1wZSAhPSBOVUxMICYmIG1wZSAtPlR5cGUgPT0gY21zU2lnQ3VydmVTZXRFbGVtVHlwZSkgewogICAgICAgIFByZU1QRSA9IChfY21zU3RhZ2VUb25lQ3VydmVzRGF0YSopIG1wZSAtPkRhdGE7CiAgICAgICAgbXBlID0gbXBlIC0+IE5leHQ7CiAgICB9CgogICAgaWYgKG1wZSAhPSBOVUxMICYmIG1wZSAtPlR5cGUgPT0gY21zU2lnQ0x1dEVsZW1UeXBlKSB7CiAgICAgICAgY2x1dCAgPSAoX2Ntc1N0YWdlQ0x1dERhdGEqKSBtcGUgLT4gRGF0YTsKICAgICAgICBtcGUgPSBtcGUgLT5OZXh0OwogICAgfQoKICAgIGlmIChtcGUgIT0gTlVMTCAmJiBtcGUgLT5UeXBlID09IGNtc1NpZ0N1cnZlU2V0RWxlbVR5cGUpIHsKICAgICAgICBQb3N0TVBFID0gKF9jbXNTdGFnZVRvbmVDdXJ2ZXNEYXRhKikgbXBlIC0+RGF0YTsKICAgICAgICBtcGUgPSBtcGUgLT4gTmV4dDsKICAgIH0KCiAgICAvLyBUaGF0IHNob3VsZCBiZSBhbGwKICAgIGlmIChtcGUgIT0gTlVMTCkgewogICAgICAgIGNtc1NpZ25hbEVycm9yKG1wZS0+Q29udGV4dElELCBjbXNFUlJPUl9VTktOT1dOX0VYVEVOU0lPTiwgIkxVVCBpcyBub3Qgc3VpdGFibGUgdG8gYmUgc2F2ZWQgYXMgTFVUMTYiKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgSW5wdXRDaGFubmVscyAgPSBjbXNQaXBlbGluZUlucHV0Q2hhbm5lbHMoTmV3TFVUKTsKICAgIE91dHB1dENoYW5uZWxzID0gY21zUGlwZWxpbmVPdXRwdXRDaGFubmVscyhOZXdMVVQpOwoKICAgIGlmIChjbHV0ID09IE5VTEwpCiAgICAgICAgY2x1dFBvaW50cyA9IDA7CiAgICBlbHNlCiAgICAgICAgY2x1dFBvaW50cyAgICA9IGNsdXQtPlBhcmFtcy0+blNhbXBsZXNbMF07CgogICAgaWYgKCFfY21zV3JpdGVVSW50OE51bWJlcihpbywgKGNtc1VJbnQ4TnVtYmVyKSBJbnB1dENoYW5uZWxzKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50OE51bWJlcihpbywgKGNtc1VJbnQ4TnVtYmVyKSBPdXRwdXRDaGFubmVscykpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDhOdW1iZXIoaW8sIChjbXNVSW50OE51bWJlcikgY2x1dFBvaW50cykpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDhOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7IC8vIFBhZGRpbmcKCgogICAgaWYgKE1hdE1QRSAhPSBOVUxMKSB7CgogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBNYXRNUEUgLT4gRG91YmxlWzBdKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBNYXRNUEUgLT4gRG91YmxlWzFdKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBNYXRNUEUgLT4gRG91YmxlWzJdKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBNYXRNUEUgLT4gRG91YmxlWzNdKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBNYXRNUEUgLT4gRG91YmxlWzRdKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBNYXRNUEUgLT4gRG91YmxlWzVdKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBNYXRNUEUgLT4gRG91YmxlWzZdKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBNYXRNUEUgLT4gRG91YmxlWzddKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBNYXRNUEUgLT4gRG91YmxlWzhdKSkgcmV0dXJuIEZBTFNFOwogICAgfQogICAgZWxzZSB7CgogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAxKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAxKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAxKSkgcmV0dXJuIEZBTFNFOwogICAgfQoKCiAgICBpZiAoUHJlTVBFICE9IE5VTEwpIHsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgKGNtc1VJbnQxNk51bWJlcikgUHJlTVBFIC0+VGhlQ3VydmVzWzBdLT5uRW50cmllcykpIHJldHVybiBGQUxTRTsKICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDE2TnVtYmVyKGlvLCAyKSkgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChQb3N0TVBFICE9IE5VTEwpIHsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgKGNtc1VJbnQxNk51bWJlcikgUG9zdE1QRSAtPlRoZUN1cnZlc1swXS0+bkVudHJpZXMpKSByZXR1cm4gRkFMU0U7CiAgICB9IGVsc2UgewogICAgICAgIGlmICghX2Ntc1dyaXRlVUludDE2TnVtYmVyKGlvLCAyKSkgcmV0dXJuIEZBTFNFOwoKICAgIH0KCiAgICAvLyBUaGUgcHJlbGluZWFyaXphdGlvbiB0YWJsZQoKICAgIGlmIChQcmVNUEUgIT0gTlVMTCkgewogICAgICAgIGlmICghV3JpdGUxNmJpdFRhYmxlcyhzZWxmIC0+Q29udGV4dElELCBpbywgUHJlTVBFKSkgcmV0dXJuIEZBTFNFOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgZm9yIChpPTA7IGkgPCBJbnB1dENoYW5uZWxzOyBpKyspIHsKCiAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgMHhmZmZmKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICBuVGFiU2l6ZSA9IHVpcG93KE91dHB1dENoYW5uZWxzLCBjbHV0UG9pbnRzLCBJbnB1dENoYW5uZWxzKTsKICAgIGlmIChuVGFiU2l6ZSA9PSAoY21zVUludDMyTnVtYmVyKSAtMSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKG5UYWJTaXplID4gMCkgewogICAgICAgIC8vIFRoZSAzRCBDTFVULgogICAgICAgIGlmIChjbHV0ICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MTZBcnJheShpbywgblRhYlNpemUsIGNsdXQtPlRhYi5UKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBUaGUgcG9zdGxpbmVhcml6YXRpb24gdGFibGUKICAgIGlmIChQb3N0TVBFICE9IE5VTEwpIHsKICAgICAgICBpZiAoIVdyaXRlMTZiaXRUYWJsZXMoc2VsZiAtPkNvbnRleHRJRCwgaW8sIFBvc3RNUEUpKSByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBmb3IgKGk9MDsgaSA8IE91dHB1dENoYW5uZWxzOyBpKyspIHsKCiAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgMHhmZmZmKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7Cn0KCnN0YXRpYwp2b2lkKiBUeXBlX0xVVDE2X0R1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgIHJldHVybiAodm9pZCopIGNtc1BpcGVsaW5lRHVwKChjbXNQaXBlbGluZSopIFB0cik7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCnN0YXRpYwp2b2lkIFR5cGVfTFVUMTZfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQqIFB0cikKewogICAgY21zUGlwZWxpbmVGcmVlKChjbXNQaXBlbGluZSopIFB0cik7CiAgICByZXR1cm47CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFR5cGUgY21zU2lnTHV0QVRvQlR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCgovLyBWNCBzdHVmZi4gUmVhZCBtYXRyaXggZm9yIEx1dEF0b0IgYW5kIEx1dEJ0b0EKCnN0YXRpYwpjbXNTdGFnZSogUmVhZE1hdHJpeChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciBPZmZzZXQpCnsKICAgIGNtc0Zsb2F0NjROdW1iZXIgZE1hdFszKjNdOwogICAgY21zRmxvYXQ2NE51bWJlciBkT2ZmWzNdOwogICAgY21zU3RhZ2UqIE1hdDsKCiAgICAvLyBHbyB0byBhZGRyZXNzCiAgICBpZiAoIWlvIC0+IFNlZWsoaW8sIE9mZnNldCkpIHJldHVybiBOVUxMOwoKICAgIC8vIFJlYWQgdGhlIE1hdHJpeAogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJmRNYXRbMF0pKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWQxNUZpeGVkMTZOdW1iZXIoaW8sICZkTWF0WzFdKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAmZE1hdFsyXSkpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJmRNYXRbM10pKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWQxNUZpeGVkMTZOdW1iZXIoaW8sICZkTWF0WzRdKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAmZE1hdFs1XSkpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJmRNYXRbNl0pKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWQxNUZpeGVkMTZOdW1iZXIoaW8sICZkTWF0WzddKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAmZE1hdFs4XSkpIHJldHVybiBOVUxMOwoKICAgIGlmICghX2Ntc1JlYWQxNUZpeGVkMTZOdW1iZXIoaW8sICZkT2ZmWzBdKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAmZE9mZlsxXSkpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJmRPZmZbMl0pKSByZXR1cm4gTlVMTDsKCiAgICBNYXQgPSBjbXNTdGFnZUFsbG9jTWF0cml4KHNlbGYgLT5Db250ZXh0SUQsIDMsIDMsIGRNYXQsIGRPZmYpOwoKICAgICByZXR1cm4gTWF0Owp9CgoKCgovLyAgVjQgc3R1ZmYuIFJlYWQgQ0xVVCBwYXJ0IGZvciBMdXRBdG9CIGFuZCBMdXRCdG9BCgpzdGF0aWMKY21zU3RhZ2UqIFJlYWRDTFVUKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyIE9mZnNldCwgaW50IElucHV0Q2hhbm5lbHMsIGludCBPdXRwdXRDaGFubmVscykKewogICAgY21zVUludDhOdW1iZXIgIGdyaWRQb2ludHM4W2Ntc01BWENIQU5ORUxTXTsgLy8gTnVtYmVyIG9mIGdyaWQgcG9pbnRzIGluIGVhY2ggZGltZW5zaW9uLgogICAgY21zVUludDMyTnVtYmVyIEdyaWRQb2ludHNbY21zTUFYQ0hBTk5FTFNdLCBpOwogICAgY21zVUludDhOdW1iZXIgIFByZWNpc2lvbjsKICAgIGNtc1N0YWdlKiBDTFVUOwogICAgX2Ntc1N0YWdlQ0x1dERhdGEqIERhdGE7CgogICAgaWYgKCFpbyAtPiBTZWVrKGlvLCBPZmZzZXQpKSByZXR1cm4gTlVMTDsKICAgIGlmIChpbyAtPiBSZWFkKGlvLCBncmlkUG9pbnRzOCwgY21zTUFYQ0hBTk5FTFMsIDEpICE9IDEpIHJldHVybiBOVUxMOwoKCiAgICBmb3IgKGk9MDsgaSA8IGNtc01BWENIQU5ORUxTOyBpKyspIHsKCiAgICAgICAgaWYgKGdyaWRQb2ludHM4W2ldID09IDEpIHJldHVybiBOVUxMOyAvLyBJbXBvc3NpYmxlIHZhbHVlLCAwIGZvciBubyBDTFVUIGFuZCB0aGVuIDIgYXQgbGVhc3QKICAgICAgICBHcmlkUG9pbnRzW2ldID0gZ3JpZFBvaW50czhbaV07CiAgICB9CgogICAgaWYgKCFfY21zUmVhZFVJbnQ4TnVtYmVyKGlvLCAmUHJlY2lzaW9uKSkgcmV0dXJuIE5VTEw7CgogICAgaWYgKCFfY21zUmVhZFVJbnQ4TnVtYmVyKGlvLCBOVUxMKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkVUludDhOdW1iZXIoaW8sIE5VTEwpKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50OE51bWJlcihpbywgTlVMTCkpIHJldHVybiBOVUxMOwoKICAgIENMVVQgPSBjbXNTdGFnZUFsbG9jQ0x1dDE2Yml0R3JhbnVsYXIoc2VsZiAtPkNvbnRleHRJRCwgR3JpZFBvaW50cywgSW5wdXRDaGFubmVscywgT3V0cHV0Q2hhbm5lbHMsIE5VTEwpOwogICAgaWYgKENMVVQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgRGF0YSA9IChfY21zU3RhZ2VDTHV0RGF0YSopIENMVVQgLT5EYXRhOwoKICAgIC8vIFByZWNpc2lvbiBjYW4gYmUgMSBvciAyIGJ5dGVzCiAgICBpZiAoUHJlY2lzaW9uID09IDEpIHsKCiAgICAgICAgY21zVUludDhOdW1iZXIgIHY7CgogICAgICAgIGZvciAoaT0wOyBpIDwgRGF0YSAtPm5FbnRyaWVzOyBpKyspIHsKCiAgICAgICAgICAgIGlmIChpbyAtPlJlYWQoaW8sICZ2LCBzaXplb2YoY21zVUludDhOdW1iZXIpLCAxKSAhPSAxKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgRGF0YSAtPlRhYi5UW2ldID0gRlJPTV84X1RPXzE2KHYpOwogICAgICAgIH0KCiAgICB9CiAgICBlbHNlCiAgICAgICAgaWYgKFByZWNpc2lvbiA9PSAyKSB7CgogICAgICAgICAgICBpZiAoIV9jbXNSZWFkVUludDE2QXJyYXkoaW8sIERhdGEtPm5FbnRyaWVzLCBEYXRhIC0+VGFiLlQpKSB7CiAgICAgICAgICAgICAgICBjbXNTdGFnZUZyZWUoQ0xVVCk7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgY21zU3RhZ2VGcmVlKENMVVQpOwogICAgICAgICAgICBjbXNTaWduYWxFcnJvcihzZWxmIC0+Q29udGV4dElELCBjbXNFUlJPUl9VTktOT1dOX0VYVEVOU0lPTiwgIlVua25vd24gcHJlY2lzaW9uIG9mICclZCciLCBQcmVjaXNpb24pOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBDTFVUOwp9CgpzdGF0aWMKY21zVG9uZUN1cnZlKiBSZWFkRW1iZWRkZWRDdXJ2ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8pCnsKICAgIGNtc1RhZ1R5cGVTaWduYXR1cmUgIEJhc2VUeXBlOwogICAgY21zVUludDMyTnVtYmVyIG5JdGVtczsKCiAgICBCYXNlVHlwZSA9IF9jbXNSZWFkVHlwZUJhc2UoaW8pOwogICAgc3dpdGNoIChCYXNlVHlwZSkgewoKICAgICAgICAgICAgY2FzZSBjbXNTaWdDdXJ2ZVR5cGU6CiAgICAgICAgICAgICAgICByZXR1cm4gKGNtc1RvbmVDdXJ2ZSopIFR5cGVfQ3VydmVfUmVhZChzZWxmLCBpbywgJm5JdGVtcywgMCk7CgogICAgICAgICAgICBjYXNlIGNtc1NpZ1BhcmFtZXRyaWNDdXJ2ZVR5cGU6CiAgICAgICAgICAgICAgICByZXR1cm4gKGNtc1RvbmVDdXJ2ZSopIFR5cGVfUGFyYW1ldHJpY0N1cnZlX1JlYWQoc2VsZiwgaW8sICZuSXRlbXMsIDApOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIFN0cmluZ1s1XTsKCiAgICAgICAgICAgICAgICAgICAgX2Ntc1RhZ1NpZ25hdHVyZTJTdHJpbmcoU3RyaW5nLCAoY21zVGFnU2lnbmF0dXJlKSBCYXNlVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgY21zU2lnbmFsRXJyb3Ioc2VsZiAtPkNvbnRleHRJRCwgY21zRVJST1JfVU5LTk9XTl9FWFRFTlNJT04sICJVbmtub3duIGN1cnZlIHR5cGUgJyVzJyIsIFN0cmluZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KfQoKCi8vIFJlYWQgYSBzZXQgb2YgY3VydmVzIGZyb20gc3BlY2lmaWMgb2Zmc2V0CnN0YXRpYwpjbXNTdGFnZSogUmVhZFNldE9mQ3VydmVzKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyIE9mZnNldCwgY21zVUludDMyTnVtYmVyIG5DdXJ2ZXMpCnsKICAgIGNtc1RvbmVDdXJ2ZSogQ3VydmVzW2Ntc01BWENIQU5ORUxTXTsKICAgIGNtc1VJbnQzMk51bWJlciBpOwogICAgY21zU3RhZ2UqIExpbiA9IE5VTEw7CgogICAgaWYgKG5DdXJ2ZXMgPiBjbXNNQVhDSEFOTkVMUykgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghaW8gLT4gU2VlayhpbywgT2Zmc2V0KSkgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAoaT0wOyBpIDwgbkN1cnZlczsgaSsrKQogICAgICAgIEN1cnZlc1tpXSA9IE5VTEw7CgogICAgZm9yIChpPTA7IGkgPCBuQ3VydmVzOyBpKyspIHsKCiAgICAgICAgQ3VydmVzW2ldID0gUmVhZEVtYmVkZGVkQ3VydmUoc2VsZiwgaW8pOwogICAgICAgIGlmIChDdXJ2ZXNbaV0gPT0gTlVMTCkgZ290byBFcnJvcjsKICAgICAgICBpZiAoIV9jbXNSZWFkQWxpZ25tZW50KGlvKSkgZ290byBFcnJvcjsKCiAgICB9CgogICAgTGluID0gY21zU3RhZ2VBbGxvY1RvbmVDdXJ2ZXMoc2VsZiAtPkNvbnRleHRJRCwgbkN1cnZlcywgQ3VydmVzKTsKCkVycm9yOgogICAgZm9yIChpPTA7IGkgPCBuQ3VydmVzOyBpKyspCiAgICAgICAgY21zRnJlZVRvbmVDdXJ2ZShDdXJ2ZXNbaV0pOwoKICAgIHJldHVybiBMaW47Cn0KCgovLyBMdXRBdG9CIHR5cGUKCi8vIFRoaXMgc3RydWN0dXJlIHJlcHJlc2VudHMgYSBjb2xvdXIgdHJhbnNmb3JtLiBUaGUgdHlwZSBjb250YWlucyB1cCB0byBmaXZlIHByb2Nlc3NpbmcKLy8gZWxlbWVudHMgd2hpY2ggYXJlIHN0b3JlZCBpbiB0aGUgQXRvQlRhZyB0YWcgaW4gdGhlIGZvbGxvd2luZyBvcmRlcjogYSBzZXQgb2Ygb25lCi8vIGRpbWVuc2lvbmFsIGN1cnZlcywgYSAzIGJ5IDMgbWF0cml4IHdpdGggb2Zmc2V0IHRlcm1zLCBhIHNldCBvZiBvbmUgZGltZW5zaW9uYWwgY3VydmVzLAovLyBhIG11bHRpZGltZW5zaW9uYWwgbG9va3VwIHRhYmxlLCBhbmQgYSBzZXQgb2Ygb25lIGRpbWVuc2lvbmFsIG91dHB1dCBjdXJ2ZXMuCi8vIERhdGEgYXJlIHByb2Nlc3NlZCB1c2luZyB0aGVzZSBlbGVtZW50cyB2aWEgdGhlIGZvbGxvd2luZyBzZXF1ZW5jZToKLy8KLy8oIkEiIGN1cnZlcykgLT4gKG11bHRpZGltZW5zaW9uYWwgbG9va3VwIHRhYmxlIC0gQ0xVVCkgLT4gKCJNIiBjdXJ2ZXMpIC0+IChtYXRyaXgpIC0+ICgiQiIgY3VydmVzKS4KLy8KLyoKSXQgaXMgcG9zc2libGUgdG8gdXNlIGFueSBvciBhbGwgb2YgdGhlc2UgcHJvY2Vzc2luZyBlbGVtZW50cy4gQXQgbGVhc3Qgb25lIHByb2Nlc3NpbmcgZWxlbWVudAptdXN0IGJlIGluY2x1ZGVkLk9ubHkgdGhlIGZvbGxvd2luZyBjb21iaW5hdGlvbnMgYXJlIGFsbG93ZWQ6CgpCCk0gLSBNYXRyaXggLSBCCkEgLSBDTFVUIC0gQgpBIC0gQ0xVVCAtIE0gLSBNYXRyaXggLSBCCgoqLwoKc3RhdGljCnZvaWQqIFR5cGVfTFVUQTJCX1JlYWQoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNVSW50MzJOdW1iZXIqIG5JdGVtcywgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY21zVUludDMyTnVtYmVyICAgICAgQmFzZU9mZnNldDsKICAgIGNtc1VJbnQ4TnVtYmVyICAgICAgIGlucHV0Q2hhbjsgICAgICAvLyBOdW1iZXIgb2YgaW5wdXQgY2hhbm5lbHMKICAgIGNtc1VJbnQ4TnVtYmVyICAgICAgIG91dHB1dENoYW47ICAgICAvLyBOdW1iZXIgb2Ygb3V0cHV0IGNoYW5uZWxzCiAgICBjbXNVSW50MzJOdW1iZXIgICAgICBvZmZzZXRCOyAgICAgICAgLy8gT2Zmc2V0IHRvIGZpcnN0ICJCIiBjdXJ2ZQogICAgY21zVUludDMyTnVtYmVyICAgICAgb2Zmc2V0TWF0OyAgICAgIC8vIE9mZnNldCB0byBtYXRyaXgKICAgIGNtc1VJbnQzMk51bWJlciAgICAgIG9mZnNldE07ICAgICAgICAvLyBPZmZzZXQgdG8gZmlyc3QgIk0iIGN1cnZlCiAgICBjbXNVSW50MzJOdW1iZXIgICAgICBvZmZzZXRDOyAgICAgICAgLy8gT2Zmc2V0IHRvIENMVVQKICAgIGNtc1VJbnQzMk51bWJlciAgICAgIG9mZnNldEE7ICAgICAgICAvLyBPZmZzZXQgdG8gZmlyc3QgIkEiIGN1cnZlCiAgICBjbXNQaXBlbGluZSogTmV3TFVUID0gTlVMTDsKCgogICAgQmFzZU9mZnNldCA9IGlvIC0+VGVsbChpbykgLSBzaXplb2YoX2Ntc1RhZ0Jhc2UpOwoKICAgIGlmICghX2Ntc1JlYWRVSW50OE51bWJlcihpbywgJmlucHV0Q2hhbikpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZFVJbnQ4TnVtYmVyKGlvLCAmb3V0cHV0Q2hhbikpIHJldHVybiBOVUxMOwoKICAgIGlmICghX2Ntc1JlYWRVSW50MTZOdW1iZXIoaW8sIE5VTEwpKSByZXR1cm4gTlVMTDsKCiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmb2Zmc2V0QikpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJm9mZnNldE1hdCkpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJm9mZnNldE0pKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZvZmZzZXRDKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmb2Zmc2V0QSkpIHJldHVybiBOVUxMOwoKICAgLy8gQWxsb2NhdGVzIGFuIGVtcHR5IExVVAogICAgTmV3TFVUID0gY21zUGlwZWxpbmVBbGxvYyhzZWxmIC0+Q29udGV4dElELCBpbnB1dENoYW4sIG91dHB1dENoYW4pOwogICAgaWYgKE5ld0xVVCA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBpZiAob2Zmc2V0QSE9IDApIHsKICAgICAgICBpZiAoIWNtc1BpcGVsaW5lSW5zZXJ0U3RhZ2UoTmV3TFVULCBjbXNBVF9FTkQsIFJlYWRTZXRPZkN1cnZlcyhzZWxmLCBpbywgQmFzZU9mZnNldCArIG9mZnNldEEsIGlucHV0Q2hhbikpKQogICAgICAgICAgICBnb3RvIEVycm9yOwogICAgfQoKICAgIGlmIChvZmZzZXRDICE9IDApIHsKICAgICAgICBpZiAoIWNtc1BpcGVsaW5lSW5zZXJ0U3RhZ2UoTmV3TFVULCBjbXNBVF9FTkQsIFJlYWRDTFVUKHNlbGYsIGlvLCBCYXNlT2Zmc2V0ICsgb2Zmc2V0QywgaW5wdXRDaGFuLCBvdXRwdXRDaGFuKSkpCiAgICAgICAgICAgIGdvdG8gRXJyb3I7CiAgICB9CgogICAgaWYgKG9mZnNldE0gIT0gMCkgewogICAgICAgIGlmICghY21zUGlwZWxpbmVJbnNlcnRTdGFnZShOZXdMVVQsIGNtc0FUX0VORCwgUmVhZFNldE9mQ3VydmVzKHNlbGYsIGlvLCBCYXNlT2Zmc2V0ICsgb2Zmc2V0TSwgb3V0cHV0Q2hhbikpKQogICAgICAgICAgICBnb3RvIEVycm9yOwogICAgfQoKICAgIGlmIChvZmZzZXRNYXQgIT0gMCkgewogICAgICAgIGlmICghY21zUGlwZWxpbmVJbnNlcnRTdGFnZShOZXdMVVQsIGNtc0FUX0VORCwgUmVhZE1hdHJpeChzZWxmLCBpbywgQmFzZU9mZnNldCArIG9mZnNldE1hdCkpKQogICAgICAgICAgICBnb3RvIEVycm9yOwogICAgfQoKICAgIGlmIChvZmZzZXRCICE9IDApIHsKICAgICAgICBpZiAoIWNtc1BpcGVsaW5lSW5zZXJ0U3RhZ2UoTmV3TFVULCBjbXNBVF9FTkQsIFJlYWRTZXRPZkN1cnZlcyhzZWxmLCBpbywgQmFzZU9mZnNldCArIG9mZnNldEIsIG91dHB1dENoYW4pKSkKICAgICAgICAgICAgZ290byBFcnJvcjsKICAgIH0KCiAgICAqbkl0ZW1zID0gMTsKICAgIHJldHVybiBOZXdMVVQ7CkVycm9yOgogICAgY21zUGlwZWxpbmVGcmVlKE5ld0xVVCk7CiAgICByZXR1cm4gTlVMTDsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKFNpemVPZlRhZyk7Cn0KCi8vIFdyaXRlIGEgc2V0IG9mIGN1cnZlcwpzdGF0aWMKY21zQm9vbCAgV3JpdGVNYXRyaXgoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNTdGFnZSogbXBlKQp7CiAgICBfY21zU3RhZ2VNYXRyaXhEYXRhKiBtID0gKF9jbXNTdGFnZU1hdHJpeERhdGEqKSBtcGUgLT4gRGF0YTsKCiAgICAvLyBXcml0ZSB0aGUgTWF0cml4CiAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgbSAtPiBEb3VibGVbMF0pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgbSAtPiBEb3VibGVbMV0pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgbSAtPiBEb3VibGVbMl0pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgbSAtPiBEb3VibGVbM10pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgbSAtPiBEb3VibGVbNF0pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgbSAtPiBEb3VibGVbNV0pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgbSAtPiBEb3VibGVbNl0pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgbSAtPiBEb3VibGVbN10pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZTE1Rml4ZWQxNk51bWJlcihpbywgbSAtPiBEb3VibGVbOF0pKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKG0gLT5PZmZzZXQgIT0gTlVMTCkgewoKICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBtIC0+IE9mZnNldFswXSkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBtIC0+IE9mZnNldFsxXSkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBtIC0+IE9mZnNldFsyXSkpIHJldHVybiBGQUxTRTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwoKICAgIH0KCgogICAgcmV0dXJuIFRSVUU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKCi8vIFdyaXRlIGEgc2V0IG9mIGN1cnZlcwpzdGF0aWMKY21zQm9vbCBXcml0ZVNldE9mQ3VydmVzKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVGFnVHlwZVNpZ25hdHVyZSBUeXBlLCBjbXNTdGFnZSogbXBlKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgbjsKICAgIGNtc1RhZ1R5cGVTaWduYXR1cmUgQ3VycmVudFR5cGU7CiAgICBjbXNUb25lQ3VydmUqKiBDdXJ2ZXM7CgoKICAgIG4gICAgICA9IGNtc1N0YWdlT3V0cHV0Q2hhbm5lbHMobXBlKTsKICAgIEN1cnZlcyA9IF9jbXNTdGFnZUdldFB0clRvQ3VydmVTZXQobXBlKTsKCiAgICBmb3IgKGk9MDsgaSA8IG47IGkrKykgewoKICAgICAgICAvLyBJZiB0aGlzIGlzIGEgdGFibGUtYmFzZWQgY3VydmUsIHVzZSBjdXJ2ZSB0eXBlIGV2ZW4gb24gVjQKICAgICAgICBDdXJyZW50VHlwZSA9IFR5cGU7CgogICAgICAgIGlmICgoQ3VydmVzW2ldIC0+blNlZ21lbnRzID09IDApfHwKICAgICAgICAgICAgKChDdXJ2ZXNbaV0tPm5TZWdtZW50cyA9PSAyKSAmJiAoQ3VydmVzW2ldIC0+U2VnbWVudHNbMV0uVHlwZSA9PSAwKSkgKQogICAgICAgICAgICBDdXJyZW50VHlwZSA9IGNtc1NpZ0N1cnZlVHlwZTsKICAgICAgICBlbHNlCiAgICAgICAgaWYgKEN1cnZlc1tpXSAtPlNlZ21lbnRzWzBdLlR5cGUgPCAwKQogICAgICAgICAgICBDdXJyZW50VHlwZSA9IGNtc1NpZ0N1cnZlVHlwZTsKCiAgICAgICAgaWYgKCFfY21zV3JpdGVUeXBlQmFzZShpbywgQ3VycmVudFR5cGUpKSByZXR1cm4gRkFMU0U7CgogICAgICAgIHN3aXRjaCAoQ3VycmVudFR5cGUpIHsKCiAgICAgICAgICAgIGNhc2UgY21zU2lnQ3VydmVUeXBlOgogICAgICAgICAgICAgICAgaWYgKCFUeXBlX0N1cnZlX1dyaXRlKHNlbGYsIGlvLCBDdXJ2ZXNbaV0sIDEpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgY21zU2lnUGFyYW1ldHJpY0N1cnZlVHlwZToKICAgICAgICAgICAgICAgIGlmICghVHlwZV9QYXJhbWV0cmljQ3VydmVfV3JpdGUoc2VsZiwgaW8sIEN1cnZlc1tpXSwgMSkpIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIFN0cmluZ1s1XTsKCiAgICAgICAgICAgICAgICAgICAgX2Ntc1RhZ1NpZ25hdHVyZTJTdHJpbmcoU3RyaW5nLCAoY21zVGFnU2lnbmF0dXJlKSBUeXBlKTsKICAgICAgICAgICAgICAgICAgICBjbXNTaWduYWxFcnJvcihzZWxmIC0+Q29udGV4dElELCBjbXNFUlJPUl9VTktOT1dOX0VYVEVOU0lPTiwgIlVua25vd24gY3VydmUgdHlwZSAnJXMnIiwgU3RyaW5nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICB9CgogICAgICAgIGlmICghX2Ntc1dyaXRlQWxpZ25tZW50KGlvKSkgcmV0dXJuIEZBTFNFOwogICAgfQoKCiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYwpjbXNCb29sIFdyaXRlQ0xVVChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQ4TnVtYmVyICBQcmVjaXNpb24sIGNtc1N0YWdlKiBtcGUpCnsKICAgIGNtc1VJbnQ4TnVtYmVyICBncmlkUG9pbnRzW2Ntc01BWENIQU5ORUxTXTsgLy8gTnVtYmVyIG9mIGdyaWQgcG9pbnRzIGluIGVhY2ggZGltZW5zaW9uLgogICAgY21zVUludDMyTnVtYmVyIGk7CiAgICBfY21zU3RhZ2VDTHV0RGF0YSogQ0xVVCA9ICggX2Ntc1N0YWdlQ0x1dERhdGEqKSBtcGUgLT4gRGF0YTsKCiAgICBpZiAoQ0xVVCAtPkhhc0Zsb2F0VmFsdWVzKSB7CiAgICAgICAgIGNtc1NpZ25hbEVycm9yKHNlbGYgLT5Db250ZXh0SUQsIGNtc0VSUk9SX05PVF9TVUlUQUJMRSwgIkNhbm5vdCBzYXZlIGZsb2F0aW5nIHBvaW50IGRhdGEsIENMVVQgYXJlIDggb3IgMTYgYml0IG9ubHkiKTsKICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIG1lbXNldChncmlkUG9pbnRzLCAwLCBzaXplb2YoZ3JpZFBvaW50cykpOwogICAgZm9yIChpPTA7IGkgPCAoY21zVUludDMyTnVtYmVyKSBDTFVUIC0+UGFyYW1zIC0+bklucHV0czsgaSsrKQogICAgICAgIGdyaWRQb2ludHNbaV0gPSAoY21zVUludDhOdW1iZXIpIENMVVQgLT5QYXJhbXMgLT5uU2FtcGxlc1tpXTsKCiAgICBpZiAoIWlvIC0+IFdyaXRlKGlvLCBjbXNNQVhDSEFOTkVMUypzaXplb2YoY21zVUludDhOdW1iZXIpLCBncmlkUG9pbnRzKSkgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghX2Ntc1dyaXRlVUludDhOdW1iZXIoaW8sIChjbXNVSW50OE51bWJlcikgUHJlY2lzaW9uKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50OE51bWJlcihpbywgMCkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDhOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQ4TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwoKICAgIC8vIFByZWNpc2lvbiBjYW4gYmUgMSBvciAyIGJ5dGVzCiAgICBpZiAoUHJlY2lzaW9uID09IDEpIHsKCiAgICAgICAgZm9yIChpPTA7IGkgPCBDTFVULT5uRW50cmllczsgaSsrKSB7CgogICAgICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQ4TnVtYmVyKGlvLCBGUk9NXzE2X1RPXzgoQ0xVVC0+VGFiLlRbaV0pKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgICAgICBpZiAoUHJlY2lzaW9uID09IDIpIHsKCiAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDE2QXJyYXkoaW8sIENMVVQtPm5FbnRyaWVzLCBDTFVUIC0+VGFiLlQpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAgY21zU2lnbmFsRXJyb3Ioc2VsZiAtPkNvbnRleHRJRCwgY21zRVJST1JfVU5LTk9XTl9FWFRFTlNJT04sICJVbmtub3duIHByZWNpc2lvbiBvZiAnJWQnIiwgUHJlY2lzaW9uKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFfY21zV3JpdGVBbGlnbm1lbnQoaW8pKSByZXR1cm4gRkFMU0U7CgogICAgICAgIHJldHVybiBUUlVFOwp9CgoKCgpzdGF0aWMKY21zQm9vbCBUeXBlX0xVVEEyQl9Xcml0ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIHZvaWQqIFB0ciwgY21zVUludDMyTnVtYmVyIG5JdGVtcykKewogICAgY21zUGlwZWxpbmUqIEx1dCA9IChjbXNQaXBlbGluZSopIFB0cjsKICAgIGludCBpbnB1dENoYW4sIG91dHB1dENoYW47CiAgICBjbXNTdGFnZSAqQSA9IE5VTEwsICpCID0gTlVMTCwgKk0gPSBOVUxMOwogICAgY21zU3RhZ2UgKiBNYXRyaXggPSBOVUxMOwogICAgY21zU3RhZ2UgKiBDTFVUID0gTlVMTDsKICAgIGNtc1VJbnQzMk51bWJlciBvZmZzZXRCID0gMCwgb2Zmc2V0TWF0ID0gMCwgb2Zmc2V0TSA9IDAsIG9mZnNldEMgPSAwLCBvZmZzZXRBID0gMDsKICAgIGNtc1VJbnQzMk51bWJlciBCYXNlT2Zmc2V0LCBEaXJlY3RvcnlQb3MsIEN1cnJlbnRQb3M7CgogICAgLy8gR2V0IHRoZSBiYXNlIGZvciBhbGwgb2Zmc2V0cwogICAgQmFzZU9mZnNldCA9IGlvIC0+VGVsbChpbykgLSBzaXplb2YoX2Ntc1RhZ0Jhc2UpOwoKICAgIGlmIChMdXQgLT5FbGVtZW50cyAhPSBOVUxMKQogICAgICAgIGlmICghY21zUGlwZWxpbmVDaGVja0FuZFJldHJlaXZlU3RhZ2VzKEx1dCwgMSwgY21zU2lnQ3VydmVTZXRFbGVtVHlwZSwgJkIpKQogICAgICAgICAgICBpZiAoIWNtc1BpcGVsaW5lQ2hlY2tBbmRSZXRyZWl2ZVN0YWdlcyhMdXQsIDMsIGNtc1NpZ0N1cnZlU2V0RWxlbVR5cGUsIGNtc1NpZ01hdHJpeEVsZW1UeXBlLCBjbXNTaWdDdXJ2ZVNldEVsZW1UeXBlLCAmTSwgJk1hdHJpeCwgJkIpKQogICAgICAgICAgICAgICAgaWYgKCFjbXNQaXBlbGluZUNoZWNrQW5kUmV0cmVpdmVTdGFnZXMoTHV0LCAzLCBjbXNTaWdDdXJ2ZVNldEVsZW1UeXBlLCBjbXNTaWdDTHV0RWxlbVR5cGUsIGNtc1NpZ0N1cnZlU2V0RWxlbVR5cGUsICZBLCAmQ0xVVCwgJkIpKQogICAgICAgICAgICAgICAgICAgIGlmICghY21zUGlwZWxpbmVDaGVja0FuZFJldHJlaXZlU3RhZ2VzKEx1dCwgNSwgY21zU2lnQ3VydmVTZXRFbGVtVHlwZSwgY21zU2lnQ0x1dEVsZW1UeXBlLCBjbXNTaWdDdXJ2ZVNldEVsZW1UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICBjbXNTaWdNYXRyaXhFbGVtVHlwZSwgY21zU2lnQ3VydmVTZXRFbGVtVHlwZSwgJkEsICZDTFVULCAmTSwgJk1hdHJpeCwgJkIpKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zU2lnbmFsRXJyb3Ioc2VsZi0+Q29udGV4dElELCBjbXNFUlJPUl9OT1RfU1VJVEFCTEUsICJMVVQgaXMgbm90IHN1aXRhYmxlIHRvIGJlIHNhdmVkIGFzIEx1dEFUb0IiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgLy8gR2V0IGlucHV0LCBvdXRwdXQgY2hhbm5lbHMKICAgIGlucHV0Q2hhbiAgPSBjbXNQaXBlbGluZUlucHV0Q2hhbm5lbHMoTHV0KTsKICAgIG91dHB1dENoYW4gPSBjbXNQaXBlbGluZU91dHB1dENoYW5uZWxzKEx1dCk7CgogICAgLy8gV3JpdGUgY2hhbm5lbCBjb3VudAogICAgaWYgKCFfY21zV3JpdGVVSW50OE51bWJlcihpbywgKGNtc1VJbnQ4TnVtYmVyKSBpbnB1dENoYW4pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQ4TnVtYmVyKGlvLCAoY21zVUludDhOdW1iZXIpIG91dHB1dENoYW4pKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgMCkpIHJldHVybiBGQUxTRTsKCiAgICAvLyBLZWVwIGRpcmVjdG9yeSB0byBiZSBmaWxsZWQgbGF0dGVyCiAgICBEaXJlY3RvcnlQb3MgPSBpbyAtPlRlbGwoaW8pOwoKICAgIC8vIFdyaXRlIHRoZSBkaXJlY3RvcnkKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgMCkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKEEgIT0gTlVMTCkgewoKICAgICAgICBvZmZzZXRBID0gaW8gLT5UZWxsKGlvKSAtIEJhc2VPZmZzZXQ7CiAgICAgICAgaWYgKCFXcml0ZVNldE9mQ3VydmVzKHNlbGYsIGlvLCBjbXNTaWdQYXJhbWV0cmljQ3VydmVUeXBlLCBBKSkgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChDTFVUICE9IE5VTEwpIHsKICAgICAgICBvZmZzZXRDID0gaW8gLT5UZWxsKGlvKSAtIEJhc2VPZmZzZXQ7CiAgICAgICAgaWYgKCFXcml0ZUNMVVQoc2VsZiwgaW8sIEx1dCAtPlNhdmVBczhCaXRzID8gMSA6IDIsIENMVVQpKSByZXR1cm4gRkFMU0U7CgogICAgfQogICAgaWYgKE0gIT0gTlVMTCkgewoKICAgICAgICBvZmZzZXRNID0gaW8gLT5UZWxsKGlvKSAtIEJhc2VPZmZzZXQ7CiAgICAgICAgaWYgKCFXcml0ZVNldE9mQ3VydmVzKHNlbGYsIGlvLCBjbXNTaWdQYXJhbWV0cmljQ3VydmVUeXBlLCBNKSkgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChNYXRyaXggIT0gTlVMTCkgewogICAgICAgIG9mZnNldE1hdCA9IGlvIC0+VGVsbChpbykgLSBCYXNlT2Zmc2V0OwogICAgICAgIGlmICghV3JpdGVNYXRyaXgoc2VsZiwgaW8sIE1hdHJpeCkpIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoQiAhPSBOVUxMKSB7CgogICAgICAgIG9mZnNldEIgPSBpbyAtPlRlbGwoaW8pIC0gQmFzZU9mZnNldDsKICAgICAgICBpZiAoIVdyaXRlU2V0T2ZDdXJ2ZXMoc2VsZiwgaW8sIGNtc1NpZ1BhcmFtZXRyaWNDdXJ2ZVR5cGUsIEIpKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgQ3VycmVudFBvcyA9IGlvIC0+VGVsbChpbyk7CgogICAgaWYgKCFpbyAtPlNlZWsoaW8sIERpcmVjdG9yeVBvcykpIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgb2Zmc2V0QikpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBvZmZzZXRNYXQpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgb2Zmc2V0TSkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBvZmZzZXRDKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIG9mZnNldEEpKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKCFpbyAtPlNlZWsoaW8sIEN1cnJlbnRQb3MpKSByZXR1cm4gRkFMU0U7CgogICAgcmV0dXJuIFRSVUU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuSXRlbXMpOwp9CgoKc3RhdGljCnZvaWQqIFR5cGVfTFVUQTJCX0R1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgIHJldHVybiAodm9pZCopIGNtc1BpcGVsaW5lRHVwKChjbXNQaXBlbGluZSopIFB0cik7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCnN0YXRpYwp2b2lkIFR5cGVfTFVUQTJCX0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIGNtc1BpcGVsaW5lRnJlZSgoY21zUGlwZWxpbmUqKSBQdHIpOwogICAgcmV0dXJuOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCgovLyBMdXRCVG9BIHR5cGUKCnN0YXRpYwp2b2lkKiBUeXBlX0xVVEIyQV9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc1VJbnQ4TnVtYmVyICAgICAgIGlucHV0Q2hhbjsgICAgICAvLyBOdW1iZXIgb2YgaW5wdXQgY2hhbm5lbHMKICAgIGNtc1VJbnQ4TnVtYmVyICAgICAgIG91dHB1dENoYW47ICAgICAvLyBOdW1iZXIgb2Ygb3V0cHV0IGNoYW5uZWxzCiAgICBjbXNVSW50MzJOdW1iZXIgICAgICBCYXNlT2Zmc2V0OyAgICAgLy8gQWN0dWFsIHBvc2l0aW9uIGluIGZpbGUKICAgIGNtc1VJbnQzMk51bWJlciAgICAgIG9mZnNldEI7ICAgICAgICAvLyBPZmZzZXQgdG8gZmlyc3QgIkIiIGN1cnZlCiAgICBjbXNVSW50MzJOdW1iZXIgICAgICBvZmZzZXRNYXQ7ICAgICAgLy8gT2Zmc2V0IHRvIG1hdHJpeAogICAgY21zVUludDMyTnVtYmVyICAgICAgb2Zmc2V0TTsgICAgICAgIC8vIE9mZnNldCB0byBmaXJzdCAiTSIgY3VydmUKICAgIGNtc1VJbnQzMk51bWJlciAgICAgIG9mZnNldEM7ICAgICAgICAvLyBPZmZzZXQgdG8gQ0xVVAogICAgY21zVUludDMyTnVtYmVyICAgICAgb2Zmc2V0QTsgICAgICAgIC8vIE9mZnNldCB0byBmaXJzdCAiQSIgY3VydmUKICAgIGNtc1BpcGVsaW5lKiBOZXdMVVQgPSBOVUxMOwoKCiAgICBCYXNlT2Zmc2V0ID0gaW8gLT5UZWxsKGlvKSAtIHNpemVvZihfY21zVGFnQmFzZSk7CgogICAgaWYgKCFfY21zUmVhZFVJbnQ4TnVtYmVyKGlvLCAmaW5wdXRDaGFuKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkVUludDhOdW1iZXIoaW8sICZvdXRwdXRDaGFuKSkgcmV0dXJuIE5VTEw7CgogICAgLy8gUGFkZGluZwogICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgTlVMTCkpIHJldHVybiBOVUxMOwoKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZvZmZzZXRCKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmb2Zmc2V0TWF0KSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmb2Zmc2V0TSkpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJm9mZnNldEMpKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZvZmZzZXRBKSkgcmV0dXJuIE5VTEw7CgogICAgLy8gQWxsb2NhdGVzIGFuIGVtcHR5IExVVAogICAgTmV3TFVUID0gY21zUGlwZWxpbmVBbGxvYyhzZWxmIC0+Q29udGV4dElELCBpbnB1dENoYW4sIG91dHB1dENoYW4pOwogICAgaWYgKE5ld0xVVCA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBpZiAob2Zmc2V0QiAhPSAwKSB7CiAgICAgICAgaWYgKCFjbXNQaXBlbGluZUluc2VydFN0YWdlKE5ld0xVVCwgY21zQVRfRU5ELCBSZWFkU2V0T2ZDdXJ2ZXMoc2VsZiwgaW8sIEJhc2VPZmZzZXQgKyBvZmZzZXRCLCBpbnB1dENoYW4pKSkKICAgICAgICAgICAgZ290byBFcnJvcjsKICAgIH0KCiAgICBpZiAob2Zmc2V0TWF0ICE9IDApIHsKICAgICAgICBpZiAoIWNtc1BpcGVsaW5lSW5zZXJ0U3RhZ2UoTmV3TFVULCBjbXNBVF9FTkQsIFJlYWRNYXRyaXgoc2VsZiwgaW8sIEJhc2VPZmZzZXQgKyBvZmZzZXRNYXQpKSkKICAgICAgICAgICAgZ290byBFcnJvcjsKICAgIH0KCiAgICBpZiAob2Zmc2V0TSAhPSAwKSB7CiAgICAgICAgaWYgKCFjbXNQaXBlbGluZUluc2VydFN0YWdlKE5ld0xVVCwgY21zQVRfRU5ELCBSZWFkU2V0T2ZDdXJ2ZXMoc2VsZiwgaW8sIEJhc2VPZmZzZXQgKyBvZmZzZXRNLCBpbnB1dENoYW4pKSkKICAgICAgICAgICAgZ290byBFcnJvcjsKICAgIH0KCiAgICBpZiAob2Zmc2V0QyAhPSAwKSB7CiAgICAgICAgaWYgKCFjbXNQaXBlbGluZUluc2VydFN0YWdlKE5ld0xVVCwgY21zQVRfRU5ELCBSZWFkQ0xVVChzZWxmLCBpbywgQmFzZU9mZnNldCArIG9mZnNldEMsIGlucHV0Q2hhbiwgb3V0cHV0Q2hhbikpKQogICAgICAgICAgICBnb3RvIEVycm9yOwogICAgfQoKICAgIGlmIChvZmZzZXRBIT0gMCkgewogICAgICAgIGlmICghY21zUGlwZWxpbmVJbnNlcnRTdGFnZShOZXdMVVQsIGNtc0FUX0VORCwgUmVhZFNldE9mQ3VydmVzKHNlbGYsIGlvLCBCYXNlT2Zmc2V0ICsgb2Zmc2V0QSwgb3V0cHV0Q2hhbikpKQogICAgICAgICAgICBnb3RvIEVycm9yOwogICAgfQoKICAgICpuSXRlbXMgPSAxOwogICAgcmV0dXJuIE5ld0xVVDsKRXJyb3I6CiAgICBjbXNQaXBlbGluZUZyZWUoTmV3TFVUKTsKICAgIHJldHVybiBOVUxMOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoU2l6ZU9mVGFnKTsKfQoKCi8qCkIKQiAtIE1hdHJpeCAtIE0KQiAtIENMVVQgLSBBCkIgLSBNYXRyaXggLSBNIC0gQ0xVVCAtIEEKKi8KCnN0YXRpYwpjbXNCb29sICBUeXBlX0xVVEIyQV9Xcml0ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIHZvaWQqIFB0ciwgY21zVUludDMyTnVtYmVyIG5JdGVtcykKewogICAgY21zUGlwZWxpbmUqIEx1dCA9IChjbXNQaXBlbGluZSopIFB0cjsKICAgIGludCBpbnB1dENoYW4sIG91dHB1dENoYW47CiAgICBjbXNTdGFnZSAqQSA9IE5VTEwsICpCID0gTlVMTCwgKk0gPSBOVUxMOwogICAgY21zU3RhZ2UgKk1hdHJpeCA9IE5VTEw7CiAgICBjbXNTdGFnZSAqQ0xVVCA9IE5VTEw7CiAgICBjbXNVSW50MzJOdW1iZXIgb2Zmc2V0QiA9IDAsIG9mZnNldE1hdCA9IDAsIG9mZnNldE0gPSAwLCBvZmZzZXRDID0gMCwgb2Zmc2V0QSA9IDA7CiAgICBjbXNVSW50MzJOdW1iZXIgQmFzZU9mZnNldCwgRGlyZWN0b3J5UG9zLCBDdXJyZW50UG9zOwoKCiAgICBCYXNlT2Zmc2V0ID0gaW8gLT5UZWxsKGlvKSAtIHNpemVvZihfY21zVGFnQmFzZSk7CgogICAgaWYgKCFjbXNQaXBlbGluZUNoZWNrQW5kUmV0cmVpdmVTdGFnZXMoTHV0LCAxLCBjbXNTaWdDdXJ2ZVNldEVsZW1UeXBlLCAmQikpCiAgICAgICAgaWYgKCFjbXNQaXBlbGluZUNoZWNrQW5kUmV0cmVpdmVTdGFnZXMoTHV0LCAzLCBjbXNTaWdDdXJ2ZVNldEVsZW1UeXBlLCBjbXNTaWdNYXRyaXhFbGVtVHlwZSwgY21zU2lnQ3VydmVTZXRFbGVtVHlwZSwgJkIsICZNYXRyaXgsICZNKSkKICAgICAgICAgICAgaWYgKCFjbXNQaXBlbGluZUNoZWNrQW5kUmV0cmVpdmVTdGFnZXMoTHV0LCAzLCBjbXNTaWdDdXJ2ZVNldEVsZW1UeXBlLCBjbXNTaWdDTHV0RWxlbVR5cGUsIGNtc1NpZ0N1cnZlU2V0RWxlbVR5cGUsICZCLCAmQ0xVVCwgJkEpKQogICAgICAgICAgICAgICAgaWYgKCFjbXNQaXBlbGluZUNoZWNrQW5kUmV0cmVpdmVTdGFnZXMoTHV0LCA1LCBjbXNTaWdDdXJ2ZVNldEVsZW1UeXBlLCBjbXNTaWdNYXRyaXhFbGVtVHlwZSwgY21zU2lnQ3VydmVTZXRFbGVtVHlwZSwKICAgICAgICAgICAgICAgICAgICBjbXNTaWdDTHV0RWxlbVR5cGUsIGNtc1NpZ0N1cnZlU2V0RWxlbVR5cGUsICZCLCAmTWF0cml4LCAmTSwgJkNMVVQsICZBKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjbXNTaWduYWxFcnJvcihzZWxmLT5Db250ZXh0SUQsIGNtc0VSUk9SX05PVF9TVUlUQUJMRSwgIkxVVCBpcyBub3Qgc3VpdGFibGUgdG8gYmUgc2F2ZWQgYXMgTHV0QlRvQSIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICB9CgogICAgaW5wdXRDaGFuICA9IGNtc1BpcGVsaW5lSW5wdXRDaGFubmVscyhMdXQpOwogICAgb3V0cHV0Q2hhbiA9IGNtc1BpcGVsaW5lT3V0cHV0Q2hhbm5lbHMoTHV0KTsKCiAgICBpZiAoIV9jbXNXcml0ZVVJbnQ4TnVtYmVyKGlvLCAoY21zVUludDhOdW1iZXIpIGlucHV0Q2hhbikpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDhOdW1iZXIoaW8sIChjbXNVSW50OE51bWJlcikgb3V0cHV0Q2hhbikpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDE2TnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwoKICAgIERpcmVjdG9yeVBvcyA9IGlvIC0+VGVsbChpbyk7CgogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgMCkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIDApKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgMCkpIHJldHVybiBGQUxTRTsKCiAgICBpZiAoQSAhPSBOVUxMKSB7CgogICAgICAgIG9mZnNldEEgPSBpbyAtPlRlbGwoaW8pIC0gQmFzZU9mZnNldDsKICAgICAgICBpZiAoIVdyaXRlU2V0T2ZDdXJ2ZXMoc2VsZiwgaW8sIGNtc1NpZ1BhcmFtZXRyaWNDdXJ2ZVR5cGUsIEEpKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKENMVVQgIT0gTlVMTCkgewogICAgICAgIG9mZnNldEMgPSBpbyAtPlRlbGwoaW8pIC0gQmFzZU9mZnNldDsKICAgICAgICBpZiAoIVdyaXRlQ0xVVChzZWxmLCBpbywgTHV0IC0+U2F2ZUFzOEJpdHMgPyAxIDogMiwgQ0xVVCkpIHJldHVybiBGQUxTRTsKCiAgICB9CiAgICBpZiAoTSAhPSBOVUxMKSB7CgogICAgICAgIG9mZnNldE0gPSBpbyAtPlRlbGwoaW8pIC0gQmFzZU9mZnNldDsKICAgICAgICBpZiAoIVdyaXRlU2V0T2ZDdXJ2ZXMoc2VsZiwgaW8sIGNtc1NpZ1BhcmFtZXRyaWNDdXJ2ZVR5cGUsIE0pKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKE1hdHJpeCAhPSBOVUxMKSB7CiAgICAgICAgb2Zmc2V0TWF0ID0gaW8gLT5UZWxsKGlvKSAtIEJhc2VPZmZzZXQ7CiAgICAgICAgaWYgKCFXcml0ZU1hdHJpeChzZWxmLCBpbywgTWF0cml4KSkgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChCICE9IE5VTEwpIHsKCiAgICAgICAgb2Zmc2V0QiA9IGlvIC0+VGVsbChpbykgLSBCYXNlT2Zmc2V0OwogICAgICAgIGlmICghV3JpdGVTZXRPZkN1cnZlcyhzZWxmLCBpbywgY21zU2lnUGFyYW1ldHJpY0N1cnZlVHlwZSwgQikpIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBDdXJyZW50UG9zID0gaW8gLT5UZWxsKGlvKTsKCiAgICBpZiAoIWlvIC0+U2VlayhpbywgRGlyZWN0b3J5UG9zKSkgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBvZmZzZXRCKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIG9mZnNldE1hdCkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBvZmZzZXRNKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIG9mZnNldEMpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgb2Zmc2V0QSkpIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIWlvIC0+U2VlayhpbywgQ3VycmVudFBvcykpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7Cn0KCgoKc3RhdGljCnZvaWQqIFR5cGVfTFVUQjJBX0R1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgIHJldHVybiAodm9pZCopIGNtc1BpcGVsaW5lRHVwKChjbXNQaXBlbGluZSopIFB0cik7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCnN0YXRpYwp2b2lkIFR5cGVfTFVUQjJBX0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIGNtc1BpcGVsaW5lRnJlZSgoY21zUGlwZWxpbmUqKSBQdHIpOwogICAgcmV0dXJuOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBjbXNTaWdDb2xvcmFudFRhYmxlVHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovKgpUaGUgcHVycG9zZSBvZiB0aGlzIHRhZyBpcyB0byBpZGVudGlmeSB0aGUgY29sb3JhbnRzIHVzZWQgaW4gdGhlIHByb2ZpbGUgYnkgYQp1bmlxdWUgbmFtZSBhbmQgc2V0IG9mIFhZWiBvciBMKmEqYiogdmFsdWVzIHRvIGdpdmUgdGhlIGNvbG9yYW50IGFuIHVuYW1iaWd1b3VzCnZhbHVlLiBUaGUgZmlyc3QgY29sb3JhbnQgbGlzdGVkIGlzIHRoZSBjb2xvcmFudCBvZiB0aGUgZmlyc3QgZGV2aWNlIGNoYW5uZWwgb2YKYSBsdXQgdGFnLiBUaGUgc2Vjb25kIGNvbG9yYW50IGxpc3RlZCBpcyB0aGUgY29sb3JhbnQgb2YgdGhlIHNlY29uZCBkZXZpY2UgY2hhbm5lbApvZiBhIGx1dCB0YWcsIGFuZCBzbyBvbi4KKi8KCnN0YXRpYwp2b2lkICpUeXBlX0NvbG9yYW50VGFibGVfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgQ291bnQ7CiAgICBjbXNOQU1FRENPTE9STElTVCogTGlzdDsKICAgIGNoYXIgTmFtZVszNF07CiAgICBjbXNVSW50MTZOdW1iZXIgUENTWzNdOwoKCiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmQ291bnQpKSByZXR1cm4gTlVMTDsKCiAgICBpZiAoQ291bnQgPiBjbXNNQVhDSEFOTkVMUykgewogICAgICAgIGNtc1NpZ25hbEVycm9yKHNlbGYtPkNvbnRleHRJRCwgY21zRVJST1JfUkFOR0UsICJUb28gbWFueSBjb2xvcmFudHMgJyVkJyIsIENvdW50KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBMaXN0ID0gY21zQWxsb2NOYW1lZENvbG9yTGlzdChzZWxmIC0+Q29udGV4dElELCBDb3VudCwgMCwgIiIsICIiKTsKICAgIGZvciAoaT0wOyBpIDwgQ291bnQ7IGkrKykgewoKICAgICAgICBpZiAoaW8gLT5SZWFkKGlvLCBOYW1lLCAzMiwgMSkgIT0gMSkgZ290byBFcnJvcjsKICAgICAgICBOYW1lWzMzXSA9IDA7CgogICAgICAgIGlmICghX2Ntc1JlYWRVSW50MTZBcnJheShpbywgMywgUENTKSkgZ290byBFcnJvcjsKCiAgICAgICAgaWYgKCFjbXNBcHBlbmROYW1lZENvbG9yKExpc3QsIE5hbWUsIFBDUywgTlVMTCkpIGdvdG8gRXJyb3I7CgogICAgfQoKICAgICpuSXRlbXMgPSAxOwogICAgcmV0dXJuIExpc3Q7CgpFcnJvcjoKICAgICpuSXRlbXMgPSAwOwogICAgY21zRnJlZU5hbWVkQ29sb3JMaXN0KExpc3QpOwogICAgcmV0dXJuIE5VTEw7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwp9CgoKCi8vIFNhdmVzIGEgY29sb3JhbnQgdGFibGUuIEl0IGlzIHVzaW5nIHRoZSBuYW1lZCBjb2xvciBzdHJ1Y3R1cmUgZm9yIHNpbXBsaWNpdHkgc2FrZQpzdGF0aWMKY21zQm9vbCAgVHlwZV9Db2xvcmFudFRhYmxlX1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNOQU1FRENPTE9STElTVCogTmFtZWRDb2xvckxpc3QgPSAoY21zTkFNRURDT0xPUkxJU1QqKSBQdHI7CiAgICBpbnQgaSwgbkNvbG9yczsKCiAgICBuQ29sb3JzID0gY21zTmFtZWRDb2xvckNvdW50KE5hbWVkQ29sb3JMaXN0KTsKCiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgbkNvbG9ycykpIHJldHVybiBGQUxTRTsKCiAgICBmb3IgKGk9MDsgaSA8IG5Db2xvcnM7IGkrKykgewoKICAgICAgICBjaGFyIHJvb3RbMzNdOwogICAgICAgIGNtc1VJbnQxNk51bWJlciBQQ1NbM107CgogICAgICAgIGlmICghY21zTmFtZWRDb2xvckluZm8oTmFtZWRDb2xvckxpc3QsIGksIHJvb3QsIE5VTEwsIE5VTEwsIFBDUywgTlVMTCkpIHJldHVybiAwOwogICAgICAgIHJvb3RbMzJdID0gMDsKCiAgICAgICAgaWYgKCFpbyAtPldyaXRlKGlvLCAzMiwgcm9vdCkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNkFycmF5KGlvLCAzLCBQQ1MpKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuSXRlbXMpOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKCnN0YXRpYwp2b2lkKiBUeXBlX0NvbG9yYW50VGFibGVfRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICAgY21zTkFNRURDT0xPUkxJU1QqIG5jID0gKGNtc05BTUVEQ09MT1JMSVNUKikgUHRyOwogICAgcmV0dXJuICh2b2lkKikgY21zRHVwTmFtZWRDb2xvckxpc3QobmMpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKc3RhdGljCnZvaWQgVHlwZV9Db2xvcmFudFRhYmxlX0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIGNtc0ZyZWVOYW1lZENvbG9yTGlzdCgoY21zTkFNRURDT0xPUkxJU1QqKSBQdHIpOwogICAgcmV0dXJuOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUeXBlIGNtc1NpZ05hbWVkQ29sb3IyVHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovL1RoZSBuYW1lZENvbG9yMlR5cGUgaXMgYSBjb3VudCB2YWx1ZSBhbmQgYXJyYXkgb2Ygc3RydWN0dXJlcyB0aGF0IHByb3ZpZGUgY29sb3IKLy9jb29yZGluYXRlcyBmb3IgNy1iaXQgQVNDSUkgY29sb3IgbmFtZXMuIEZvciBlYWNoIG5hbWVkIGNvbG9yLCBhIFBDUyBhbmQgb3B0aW9uYWwKLy9kZXZpY2UgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbG9yIGFyZSBnaXZlbi4gQm90aCByZXByZXNlbnRhdGlvbnMgYXJlIDE2LWJpdCB2YWx1ZXMuCi8vVGhlIGRldmljZSByZXByZXNlbnRhdGlvbiBjb3JyZXNwb25kcyB0byB0aGUgaGVhZGVyknMgk2NvbG9yIHNwYWNlIG9mIGRhdGE/ZmllbGQuCi8vVGhpcyByZXByZXNlbnRhdGlvbiBzaG91bGQgYmUgY29uc2lzdGVudCB3aXRoIHRoZSCTbnVtYmVyIG9mIGRldmljZSBjb21wb25lbnRzPy8vZmllbGQgaW4gdGhlIG5hbWVkQ29sb3IyVHlwZS4gSWYgdGhpcyBmaWVsZCBpcyAwLCBkZXZpY2UgY29vcmRpbmF0ZXMgYXJlIG5vdCBwcm92aWRlZC4KLy9UaGUgUENTIHJlcHJlc2VudGF0aW9uIGNvcnJlc3BvbmRzIHRvIHRoZSBoZWFkZXKScyBQQ1MgZmllbGQuIFRoZSBQQ1MgcmVwcmVzZW50YXRpb24KLy9pcyBhbHdheXMgcHJvdmlkZWQuIENvbG9yIG5hbWVzIGFyZSBmaXhlZC1sZW5ndGgsIDMyLWJ5dGUgZmllbGRzIGluY2x1ZGluZyBudWxsCi8vdGVybWluYXRpb24uIEluIG9yZGVyIHRvIG1haW50YWluIG1heGltdW0gcG9ydGFiaWxpdHksIGl0IGlzIHN0cm9uZ2x5IHJlY29tbWVuZGVkCi8vdGhhdCBzcGVjaWFsIGNoYXJhY3RlcnMgb2YgdGhlIDctYml0IEFTQ0lJIHNldCBub3QgYmUgdXNlZC4KCnN0YXRpYwp2b2lkICpUeXBlX05hbWVkQ29sb3JfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CgogICAgY21zVUludDMyTnVtYmVyICAgICAgdmVuZG9yRmxhZzsgICAgIC8vIEJvdHRvbSAxNiBiaXRzIGZvciBJQ0MgdXNlCiAgICBjbXNVSW50MzJOdW1iZXIgICAgICBjb3VudDsgICAgICAgICAgLy8gQ291bnQgb2YgbmFtZWQgY29sb3JzCiAgICBjbXNVSW50MzJOdW1iZXIgICAgICBuRGV2aWNlQ29vcmRzOyAgLy8gTnVtIG9mIGRldmljZSBjb29yZGluYXRlcwogICAgY2hhciAgICAgICAgICAgICAgICAgcHJlZml4WzMyXTsgICAgIC8vIFByZWZpeCBmb3IgZWFjaCBjb2xvciBuYW1lCiAgICBjaGFyICAgICAgICAgICAgICAgICBzdWZmaXhbMzJdOyAgICAgLy8gU3VmZml4IGZvciBlYWNoIGNvbG9yIG5hbWUKICAgIGNtc05BTUVEQ09MT1JMSVNUKiAgdjsKICAgIGNtc1VJbnQzMk51bWJlciBpOwoKCiAgICAqbkl0ZW1zID0gMDsKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZ2ZW5kb3JGbGFnKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmY291bnQpKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZuRGV2aWNlQ29vcmRzKSkgcmV0dXJuIE5VTEw7CgogICAgaWYgKGlvIC0+IFJlYWQoaW8sIHByZWZpeCwgMzIsIDEpICE9IDEpIHJldHVybiBOVUxMOwogICAgaWYgKGlvIC0+IFJlYWQoaW8sIHN1ZmZpeCwgMzIsIDEpICE9IDEpIHJldHVybiBOVUxMOwoKICAgIHByZWZpeFszMV0gPSBzdWZmaXhbMzFdID0gMDsKCiAgICB2ID0gY21zQWxsb2NOYW1lZENvbG9yTGlzdChzZWxmIC0+Q29udGV4dElELCBjb3VudCwgbkRldmljZUNvb3JkcywgcHJlZml4LCBzdWZmaXgpOwogICAgaWYgKHYgPT0gTlVMTCkgewogICAgICAgIGNtc1NpZ25hbEVycm9yKHNlbGYtPkNvbnRleHRJRCwgY21zRVJST1JfUkFOR0UsICJUb28gbWFueSBuYW1lZCBjb2xvcnMgJyVkJyIsIGNvdW50KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAobkRldmljZUNvb3JkcyA+IGNtc01BWENIQU5ORUxTKSB7CiAgICAgICAgY21zU2lnbmFsRXJyb3Ioc2VsZi0+Q29udGV4dElELCBjbXNFUlJPUl9SQU5HRSwgIlRvbyBtYW55IGRldmljZSBjb29yZGluYXRlcyAnJWQnIiwgbkRldmljZUNvb3Jkcyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBmb3IgKGk9MDsgaSA8IGNvdW50OyBpKyspIHsKCiAgICAgICAgY21zVUludDE2TnVtYmVyIFBDU1szXTsKICAgICAgICBjbXNVSW50MTZOdW1iZXIgQ29sb3JhbnRbY21zTUFYQ0hBTk5FTFNdOwogICAgICAgIGNoYXIgUm9vdFszM107CgogICAgICAgIG1lbXNldChDb2xvcmFudCwgMCwgc2l6ZW9mKENvbG9yYW50KSk7CiAgICAgICAgaWYgKGlvIC0+IFJlYWQoaW8sIFJvb3QsIDMyLCAxKSAhPSAxKSByZXR1cm4gTlVMTDsKICAgICAgICBpZiAoIV9jbXNSZWFkVUludDE2QXJyYXkoaW8sIDMsIFBDUykpIGdvdG8gRXJyb3I7CiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNkFycmF5KGlvLCBuRGV2aWNlQ29vcmRzLCBDb2xvcmFudCkpIGdvdG8gRXJyb3I7CgogICAgICAgIGlmICghY21zQXBwZW5kTmFtZWRDb2xvcih2LCBSb290LCBQQ1MsIENvbG9yYW50KSkgZ290byBFcnJvcjsKICAgIH0KCiAgICAqbkl0ZW1zID0gMTsKICAgIHJldHVybiAodm9pZCopIHYgOwoKRXJyb3I6CiAgICBjbXNGcmVlTmFtZWRDb2xvckxpc3Qodik7CiAgICByZXR1cm4gTlVMTDsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKFNpemVPZlRhZyk7Cn0KCgovLyBTYXZlcyBhIG5hbWVkIGNvbG9yIGxpc3QgaW50byBhIG5hbWVkIGNvbG9yIHByb2ZpbGUKc3RhdGljCmNtc0Jvb2wgVHlwZV9OYW1lZENvbG9yX1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNOQU1FRENPTE9STElTVCogTmFtZWRDb2xvckxpc3QgPSAoY21zTkFNRURDT0xPUkxJU1QqKSBQdHI7CiAgICBjaGFyICAgICAgICAgICAgICAgIHByZWZpeFszMl07ICAgICAvLyBQcmVmaXggZm9yIGVhY2ggY29sb3IgbmFtZQogICAgY2hhciAgICAgICAgICAgICAgICBzdWZmaXhbMzJdOyAgICAgLy8gU3VmZml4IGZvciBlYWNoIGNvbG9yIG5hbWUKICAgIGludCBpLCBuQ29sb3JzOwoKICAgIG5Db2xvcnMgPSBjbXNOYW1lZENvbG9yQ291bnQoTmFtZWRDb2xvckxpc3QpOwoKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCAwKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIG5Db2xvcnMpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgTmFtZWRDb2xvckxpc3QgLT5Db2xvcmFudENvdW50KSkgcmV0dXJuIEZBTFNFOwoKICAgIHN0cm5jcHkocHJlZml4LCAoY29uc3QgY2hhciopIE5hbWVkQ29sb3JMaXN0LT5QcmVmaXgsIDMyKTsKICAgIHN0cm5jcHkoc3VmZml4LCAoY29uc3QgY2hhciopIE5hbWVkQ29sb3JMaXN0LT5TdWZmaXgsIDMyKTsKCiAgICBzdWZmaXhbMzFdID0gcHJlZml4WzMxXSA9IDA7CgogICAgaWYgKCFpbyAtPldyaXRlKGlvLCAzMiwgcHJlZml4KSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFpbyAtPldyaXRlKGlvLCAzMiwgc3VmZml4KSkgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAoaT0wOyBpIDwgbkNvbG9yczsgaSsrKSB7CgogICAgICAgY21zVUludDE2TnVtYmVyIFBDU1szXTsKICAgICAgIGNtc1VJbnQxNk51bWJlciBDb2xvcmFudFtjbXNNQVhDSEFOTkVMU107CiAgICAgICBjaGFyIFJvb3RbMzNdOwoKICAgICAgICBpZiAoIWNtc05hbWVkQ29sb3JJbmZvKE5hbWVkQ29sb3JMaXN0LCBpLCBSb290LCBOVUxMLCBOVUxMLCBQQ1MsIENvbG9yYW50KSkgcmV0dXJuIDA7CiAgICAgICAgaWYgKCFpbyAtPldyaXRlKGlvLCAzMiAsIFJvb3QpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MTZBcnJheShpbywgMywgUENTKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlVUludDE2QXJyYXkoaW8sIE5hbWVkQ29sb3JMaXN0IC0+Q29sb3JhbnRDb3VudCwgQ29sb3JhbnQpKSByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuSXRlbXMpOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKc3RhdGljCnZvaWQqIFR5cGVfTmFtZWRDb2xvcl9EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICBjbXNOQU1FRENPTE9STElTVCogbmMgPSAoY21zTkFNRURDT0xPUkxJU1QqKSBQdHI7CgogICAgcmV0dXJuICh2b2lkKikgY21zRHVwTmFtZWRDb2xvckxpc3QobmMpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKc3RhdGljCnZvaWQgVHlwZV9OYW1lZENvbG9yX0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIGNtc0ZyZWVOYW1lZENvbG9yTGlzdCgoY21zTkFNRURDT0xPUkxJU1QqKSBQdHIpOwogICAgcmV0dXJuOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUeXBlIGNtc1NpZ1Byb2ZpbGVTZXF1ZW5jZURlc2NUeXBlCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgovLyBUaGlzIHR5cGUgaXMgYW4gYXJyYXkgb2Ygc3RydWN0dXJlcywgZWFjaCBvZiB3aGljaCBjb250YWlucyBpbmZvcm1hdGlvbiBmcm9tIHRoZQovLyBoZWFkZXIgZmllbGRzIGFuZCB0YWdzIGZyb20gdGhlIG9yaWdpbmFsIHByb2ZpbGVzIHdoaWNoIHdlcmUgY29tYmluZWQgdG8gY3JlYXRlCi8vIHRoZSBmaW5hbCBwcm9maWxlLiBUaGUgb3JkZXIgb2YgdGhlIHN0cnVjdHVyZXMgaXMgdGhlIG9yZGVyIGluIHdoaWNoIHRoZSBwcm9maWxlcwovLyB3ZXJlIGNvbWJpbmVkIGFuZCBpbmNsdWRlcyBhIHN0cnVjdHVyZSBmb3IgdGhlIGZpbmFsIHByb2ZpbGUuIFRoaXMgcHJvdmlkZXMgYQovLyBkZXNjcmlwdGlvbiBvZiB0aGUgcHJvZmlsZSBzZXF1ZW5jZSBmcm9tIHNvdXJjZSB0byBkZXN0aW5hdGlvbiwKLy8gdHlwaWNhbGx5IHVzZWQgd2l0aCB0aGUgRGV2aWNlTGluayBwcm9maWxlLgoKc3RhdGljCmNtc0Jvb2wgUmVhZEVtYmVkZGVkVGV4dChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc01MVSoqIG1sdSwgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY21zVGFnVHlwZVNpZ25hdHVyZSAgQmFzZVR5cGU7CiAgICBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zOwoKICAgIEJhc2VUeXBlID0gX2Ntc1JlYWRUeXBlQmFzZShpbyk7CgogICAgc3dpdGNoIChCYXNlVHlwZSkgewoKICAgICAgIGNhc2UgY21zU2lnVGV4dFR5cGU6CiAgICAgICAgICAgaWYgKCptbHUpIGNtc01MVWZyZWUoKm1sdSk7CiAgICAgICAgICAgKm1sdSA9IChjbXNNTFUqKVR5cGVfVGV4dF9SZWFkKHNlbGYsIGlvLCAmbkl0ZW1zLCBTaXplT2ZUYWcpOwogICAgICAgICAgIHJldHVybiAoKm1sdSAhPSBOVUxMKTsKCiAgICAgICBjYXNlIGNtc1NpZ1RleHREZXNjcmlwdGlvblR5cGU6CiAgICAgICAgICAgaWYgKCptbHUpIGNtc01MVWZyZWUoKm1sdSk7CiAgICAgICAgICAgKm1sdSA9ICAoY21zTUxVKikgVHlwZV9UZXh0X0Rlc2NyaXB0aW9uX1JlYWQoc2VsZiwgaW8sICZuSXRlbXMsIFNpemVPZlRhZyk7CiAgICAgICAgICAgcmV0dXJuICgqbWx1ICE9IE5VTEwpOwoKICAgICAgICAgICAvKgogICAgICAgICAgIFRCRDogU2l6ZSBpcyBuZWVkZWQgZm9yIE1MVSwgYW5kIHdlIGhhdmUgbm8gaWRlYSBvbiB3aGljaCBpcyB0aGUgYXZhaWxhYmxlIHNpemUKICAgICAgICAgICAqLwoKICAgICAgIGNhc2UgY21zU2lnTXVsdGlMb2NhbGl6ZWRVbmljb2RlVHlwZToKICAgICAgICAgICBpZiAoKm1sdSkgY21zTUxVZnJlZSgqbWx1KTsKICAgICAgICAgICAqbWx1ID0gIChjbXNNTFUqKSBUeXBlX01MVV9SZWFkKHNlbGYsIGlvLCAmbkl0ZW1zLCBTaXplT2ZUYWcpOwogICAgICAgICAgIHJldHVybiAoKm1sdSAhPSBOVUxMKTsKCiAgICAgICBkZWZhdWx0OiByZXR1cm4gRkFMU0U7CiAgICB9Cn0KCgpzdGF0aWMKdm9pZCAqVHlwZV9Qcm9maWxlU2VxdWVuY2VEZXNjX1JlYWQoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNVSW50MzJOdW1iZXIqIG5JdGVtcywgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY21zU0VRKiBPdXRTZXE7CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgQ291bnQ7CgogICAgKm5JdGVtcyA9IDA7CgogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJkNvdW50KSkgcmV0dXJuIE5VTEw7CgogICAgaWYgKFNpemVPZlRhZyA8IHNpemVvZihjbXNVSW50MzJOdW1iZXIpKSByZXR1cm4gTlVMTDsKICAgIFNpemVPZlRhZyAtPSBzaXplb2YoY21zVUludDMyTnVtYmVyKTsKCgogICAgT3V0U2VxID0gY21zQWxsb2NQcm9maWxlU2VxdWVuY2VEZXNjcmlwdGlvbihzZWxmIC0+Q29udGV4dElELCBDb3VudCk7CiAgICBpZiAoT3V0U2VxID09IE5VTEwpIHJldHVybiBOVUxMOwoKICAgIE91dFNlcSAtPm4gPSBDb3VudDsKCiAgICAvLyBHZXQgc3RydWN0dXJlcyBhcyB3ZWxsCgogICAgZm9yIChpPTA7IGkgPCBDb3VudDsgaSsrKSB7CgogICAgICAgIGNtc1BTRVFERVNDKiBzZWMgPSAmT3V0U2VxIC0+IHNlcVtpXTsKCiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJnNlYyAtPmRldmljZU1mZykpIGdvdG8gRXJyb3I7CiAgICAgICAgaWYgKFNpemVPZlRhZyA8IHNpemVvZihjbXNVSW50MzJOdW1iZXIpKSBnb3RvIEVycm9yOwogICAgICAgIFNpemVPZlRhZyAtPSBzaXplb2YoY21zVUludDMyTnVtYmVyKTsKCiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJnNlYyAtPmRldmljZU1vZGVsKSkgZ290byBFcnJvcjsKICAgICAgICBpZiAoU2l6ZU9mVGFnIDwgc2l6ZW9mKGNtc1VJbnQzMk51bWJlcikpIGdvdG8gRXJyb3I7CiAgICAgICAgU2l6ZU9mVGFnIC09IHNpemVvZihjbXNVSW50MzJOdW1iZXIpOwoKICAgICAgICBpZiAoIV9jbXNSZWFkVUludDY0TnVtYmVyKGlvLCAmc2VjIC0+YXR0cmlidXRlcykpIGdvdG8gRXJyb3I7CiAgICAgICAgaWYgKFNpemVPZlRhZyA8IHNpemVvZihjbXNVSW50NjROdW1iZXIpKSBnb3RvIEVycm9yOwogICAgICAgIFNpemVPZlRhZyAtPSBzaXplb2YoY21zVUludDY0TnVtYmVyKTsKCiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgKGNtc1VJbnQzMk51bWJlciAqKSZzZWMgLT50ZWNobm9sb2d5KSkgZ290byBFcnJvcjsKICAgICAgICBpZiAoU2l6ZU9mVGFnIDwgc2l6ZW9mKGNtc1VJbnQzMk51bWJlcikpIGdvdG8gRXJyb3I7CiAgICAgICAgU2l6ZU9mVGFnIC09IHNpemVvZihjbXNVSW50MzJOdW1iZXIpOwoKICAgICAgICBpZiAoIVJlYWRFbWJlZGRlZFRleHQoc2VsZiwgaW8sICZzZWMgLT5NYW51ZmFjdHVyZXIsIFNpemVPZlRhZykpIGdvdG8gRXJyb3I7CiAgICAgICAgaWYgKCFSZWFkRW1iZWRkZWRUZXh0KHNlbGYsIGlvLCAmc2VjIC0+TW9kZWwsIFNpemVPZlRhZykpIGdvdG8gRXJyb3I7CiAgICB9CgogICAgKm5JdGVtcyA9IDE7CiAgICByZXR1cm4gT3V0U2VxOwoKRXJyb3I6CiAgICBjbXNGcmVlUHJvZmlsZVNlcXVlbmNlRGVzY3JpcHRpb24oT3V0U2VxKTsKICAgIHJldHVybiBOVUxMOwp9CgoKLy8gQXV4LS1FbWJlZCBhIHRleHQgZGVzY3JpcHRpb24gdHlwZS4gSXQgY2FuIGJlIG9mIHR5cGUgdGV4dCBkZXNjcmlwdGlvbiBvciBtdWx0aWxvY2FsaXplZCB1bmljb2RlCi8vIGFuZCBpdCBkZXBlbmRzIG9mIHRoZSB2ZXJzaW9uIG51bWJlciBwYXNzZWQgb24gY21zVGFnRGVzY3JpcHRvciBzdHJ1Y3R1cmUgaW5zdGVhZCBvZiBzdGFjawpzdGF0aWMKY21zQm9vbCAgU2F2ZURlc2NyaXB0aW9uKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zTUxVKiBUZXh0KQp7CiAgICBpZiAoc2VsZiAtPklDQ1ZlcnNpb24gPCAweDQwMDAwMDApIHsKCiAgICAgICAgaWYgKCFfY21zV3JpdGVUeXBlQmFzZShpbywgY21zU2lnVGV4dERlc2NyaXB0aW9uVHlwZSkpIHJldHVybiBGQUxTRTsKICAgICAgICByZXR1cm4gVHlwZV9UZXh0X0Rlc2NyaXB0aW9uX1dyaXRlKHNlbGYsIGlvLCBUZXh0LCAxKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGlmICghX2Ntc1dyaXRlVHlwZUJhc2UoaW8sIGNtc1NpZ011bHRpTG9jYWxpemVkVW5pY29kZVR5cGUpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgcmV0dXJuIFR5cGVfTUxVX1dyaXRlKHNlbGYsIGlvLCBUZXh0LCAxKTsKICAgIH0KfQoKCnN0YXRpYwpjbXNCb29sICBUeXBlX1Byb2ZpbGVTZXF1ZW5jZURlc2NfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc1NFUSogU2VxID0gKGNtc1NFUSopIFB0cjsKICAgIGNtc1VJbnQzMk51bWJlciBpOwoKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBTZXEtPm4pKSByZXR1cm4gRkFMU0U7CgogICAgZm9yIChpPTA7IGkgPCBTZXEgLT5uOyBpKyspIHsKCiAgICAgICAgY21zUFNFUURFU0MqIHNlYyA9ICZTZXEgLT4gc2VxW2ldOwoKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgc2VjIC0+ZGV2aWNlTWZnKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBzZWMgLT5kZXZpY2VNb2RlbCkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQ2NE51bWJlcihpbywgJnNlYyAtPmF0dHJpYnV0ZXMpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIHNlYyAtPnRlY2hub2xvZ3kpKSByZXR1cm4gRkFMU0U7CgogICAgICAgIGlmICghU2F2ZURlc2NyaXB0aW9uKHNlbGYsIGlvLCBzZWMgLT5NYW51ZmFjdHVyZXIpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFTYXZlRGVzY3JpcHRpb24oc2VsZiwgaW8sIHNlYyAtPk1vZGVsKSkgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgICByZXR1cm4gVFJVRTsKCiAgICAgY21zVU5VU0VEX1BBUkFNRVRFUihuSXRlbXMpOwp9CgoKc3RhdGljCnZvaWQqIFR5cGVfUHJvZmlsZVNlcXVlbmNlRGVzY19EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICByZXR1cm4gKHZvaWQqKSBjbXNEdXBQcm9maWxlU2VxdWVuY2VEZXNjcmlwdGlvbigoY21zU0VRKikgUHRyKTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG4pOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKc3RhdGljCnZvaWQgVHlwZV9Qcm9maWxlU2VxdWVuY2VEZXNjX0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIGNtc0ZyZWVQcm9maWxlU2VxdWVuY2VEZXNjcmlwdGlvbigoY21zU0VRKikgUHRyKTsKICAgIHJldHVybjsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBjbXNTaWdQcm9maWxlU2VxdWVuY2VJZFR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLyoKSW4gY2VydGFpbiB3b3JrZmxvd3MgdXNpbmcgSUNDIERldmljZSBMaW5rIFByb2ZpbGVzLCBpdCBpcyBuZWNlc3NhcnkgdG8gaWRlbnRpZnkgdGhlCm9yaWdpbmFsIHByb2ZpbGVzIHRoYXQgd2VyZSBjb21iaW5lZCB0byBjcmVhdGUgdGhlIERldmljZSBMaW5rIFByb2ZpbGUuClRoaXMgdHlwZSBpcyBhbiBhcnJheSBvZiBzdHJ1Y3R1cmVzLCBlYWNoIG9mIHdoaWNoIGNvbnRhaW5zIGluZm9ybWF0aW9uIGZvcgppZGVudGlmaWNhdGlvbiBvZiBhIHByb2ZpbGUgdXNlZCBpbiBhIHNlcXVlbmNlCiovCgoKc3RhdGljCmNtc0Jvb2wgUmVhZFNlcUlEKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zSU9IQU5ETEVSKiBpbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogQ2FyZ28sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNTRVEqIE91dFNlcSA9IChjbXNTRVEqKSBDYXJnbzsKICAgIGNtc1BTRVFERVNDKiBzZXEgPSAmT3V0U2VxIC0+c2VxW25dOwoKICAgIGlmIChpbyAtPiBSZWFkKGlvLCBzZXEgLT5Qcm9maWxlSUQuSUQ4LCAxNiwgMSkgIT0gMSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFSZWFkRW1iZWRkZWRUZXh0KHNlbGYsIGlvLCAmc2VxIC0+RGVzY3JpcHRpb24sIFNpemVPZlRhZykpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCgpzdGF0aWMKdm9pZCAqVHlwZV9Qcm9maWxlU2VxdWVuY2VJZF9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc1NFUSogT3V0U2VxOwogICAgY21zVUludDMyTnVtYmVyIENvdW50OwogICAgY21zVUludDMyTnVtYmVyIEJhc2VPZmZzZXQ7CgogICAgKm5JdGVtcyA9IDA7CgogICAgLy8gR2V0IGFjdHVhbCBwb3NpdGlvbiBhcyBhIGJhc2lzIGZvciBlbGVtZW50IG9mZnNldHMKICAgIEJhc2VPZmZzZXQgPSBpbyAtPlRlbGwoaW8pIC0gc2l6ZW9mKF9jbXNUYWdCYXNlKTsKCiAgICAvLyBHZXQgdGFibGUgY291bnQKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZDb3VudCkpIHJldHVybiBOVUxMOwogICAgU2l6ZU9mVGFnIC09IHNpemVvZihjbXNVSW50MzJOdW1iZXIpOwoKICAgIC8vIEFsbG9jYXRlIGFuIGVtcHR5IHN0cnVjdHVyZQogICAgT3V0U2VxID0gY21zQWxsb2NQcm9maWxlU2VxdWVuY2VEZXNjcmlwdGlvbihzZWxmIC0+Q29udGV4dElELCBDb3VudCk7CiAgICBpZiAoT3V0U2VxID09IE5VTEwpIHJldHVybiBOVUxMOwoKCiAgICAvLyBSZWFkIHRoZSBwb3NpdGlvbiB0YWJsZQogICAgaWYgKCFSZWFkUG9zaXRpb25UYWJsZShzZWxmLCBpbywgQ291bnQsIEJhc2VPZmZzZXQsIE91dFNlcSwgUmVhZFNlcUlEKSkgewoKICAgICAgICBjbXNGcmVlUHJvZmlsZVNlcXVlbmNlRGVzY3JpcHRpb24oT3V0U2VxKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvLyBTdWNjZXNzCiAgICAqbkl0ZW1zID0gMTsKICAgIHJldHVybiBPdXRTZXE7Cgp9CgoKc3RhdGljCmNtc0Jvb2wgV3JpdGVTZXFJRChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtc0lPSEFORExFUiogaW8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIENhcmdvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY21zU0VRKiBTZXEgPSAoY21zU0VRKikgQ2FyZ287CgogICAgaWYgKCFpbyAtPldyaXRlKGlvLCAxNiwgU2VxIC0+c2VxW25dLlByb2ZpbGVJRC5JRDgpKSByZXR1cm4gRkFMU0U7CgogICAgLy8gU3RvcmUgaGVyZSB0aGUgTUxVCiAgICBpZiAoIVNhdmVEZXNjcmlwdGlvbihzZWxmLCBpbywgU2VxIC0+c2VxW25dLkRlc2NyaXB0aW9uKSkgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBUUlVFOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoU2l6ZU9mVGFnKTsKfQoKc3RhdGljCmNtc0Jvb2wgIFR5cGVfUHJvZmlsZVNlcXVlbmNlSWRfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc1NFUSogU2VxID0gKGNtc1NFUSopIFB0cjsKICAgIGNtc1VJbnQzMk51bWJlciBCYXNlT2Zmc2V0OwoKICAgIC8vIEtlZXAgdGhlIGJhc2Ugb2Zmc2V0CiAgICBCYXNlT2Zmc2V0ID0gaW8gLT5UZWxsKGlvKSAtIHNpemVvZihfY21zVGFnQmFzZSk7CgogICAgLy8gVGhpcyBpcyB0aGUgdGFibGUgY291bnQKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBTZXEgLT5uKSkgcmV0dXJuIEZBTFNFOwoKICAgIC8vIFRoaXMgaXMgdGhlIHBvc2l0aW9uIHRhYmxlIGFuZCBjb250ZW50CiAgICBpZiAoIVdyaXRlUG9zaXRpb25UYWJsZShzZWxmLCBpbywgMCwgU2VxIC0+biwgQmFzZU9mZnNldCwgU2VxLCBXcml0ZVNlcUlEKSkgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBUUlVFOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKfQoKc3RhdGljCnZvaWQqIFR5cGVfUHJvZmlsZVNlcXVlbmNlSWRfRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICAgcmV0dXJuICh2b2lkKikgY21zRHVwUHJvZmlsZVNlcXVlbmNlRGVzY3JpcHRpb24oKGNtc1NFUSopIFB0cik7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCnN0YXRpYwp2b2lkIFR5cGVfUHJvZmlsZVNlcXVlbmNlSWRfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQqIFB0cikKewogICAgY21zRnJlZVByb2ZpbGVTZXF1ZW5jZURlc2NyaXB0aW9uKChjbXNTRVEqKSBQdHIpOwogICAgcmV0dXJuOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUeXBlIGNtc1NpZ1VjckJnVHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovKgpUaGlzIHR5cGUgY29udGFpbnMgY3VydmVzIHJlcHJlc2VudGluZyB0aGUgdW5kZXIgY29sb3IgcmVtb3ZhbCBhbmQgYmxhY2sKZ2VuZXJhdGlvbiBhbmQgYSB0ZXh0IHN0cmluZyB3aGljaCBpcyBhIGdlbmVyYWwgZGVzY3JpcHRpb24gb2YgdGhlIG1ldGhvZCB1c2VkCmZvciB0aGUgdWNyL2JnLgoqLwoKc3RhdGljCnZvaWQgKlR5cGVfVWNyQmdfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNVY3JCZyogbiA9IChjbXNVY3JCZyopIF9jbXNNYWxsb2NaZXJvKHNlbGYgLT5Db250ZXh0SUQsIHNpemVvZihjbXNVY3JCZykpOwogICAgY21zVUludDMyTnVtYmVyIENvdW50VWNyLCBDb3VudEJnOwogICAgY2hhciogQVNDSUlTdHJpbmc7CgogICAgKm5JdGVtcyA9IDA7CiAgICBpZiAobiA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICAvLyBGaXJzdCBjdXJ2ZSBpcyBVbmRlciBjb2xvciByZW1vdmFsCiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmQ291bnRVY3IpKSByZXR1cm4gTlVMTDsKICAgIGlmIChTaXplT2ZUYWcgPCBzaXplb2YoY21zVUludDMyTnVtYmVyKSkgcmV0dXJuIE5VTEw7CiAgICBTaXplT2ZUYWcgLT0gc2l6ZW9mKGNtc1VJbnQzMk51bWJlcik7CgogICAgbiAtPlVjciA9IGNtc0J1aWxkVGFidWxhdGVkVG9uZUN1cnZlMTYoc2VsZiAtPkNvbnRleHRJRCwgQ291bnRVY3IsIE5VTEwpOwogICAgaWYgKG4gLT5VY3IgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgaWYgKCFfY21zUmVhZFVJbnQxNkFycmF5KGlvLCBDb3VudFVjciwgbiAtPlVjci0+VGFibGUxNikpIHJldHVybiBOVUxMOwogICAgaWYgKFNpemVPZlRhZyA8IHNpemVvZihjbXNVSW50MzJOdW1iZXIpKSByZXR1cm4gTlVMTDsKICAgIFNpemVPZlRhZyAtPSBDb3VudFVjciAqIHNpemVvZihjbXNVSW50MTZOdW1iZXIpOwoKICAgIC8vIFNlY29uZCBjdXJ2ZSBpcyBCbGFjayBnZW5lcmF0aW9uCiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmQ291bnRCZykpIHJldHVybiBOVUxMOwogICAgaWYgKFNpemVPZlRhZyA8IHNpemVvZihjbXNVSW50MzJOdW1iZXIpKSByZXR1cm4gTlVMTDsKICAgIFNpemVPZlRhZyAtPSBzaXplb2YoY21zVUludDMyTnVtYmVyKTsKCiAgICBuIC0+QmcgPSBjbXNCdWlsZFRhYnVsYXRlZFRvbmVDdXJ2ZTE2KHNlbGYgLT5Db250ZXh0SUQsIENvdW50QmcsIE5VTEwpOwogICAgaWYgKG4gLT5CZyA9PSBOVUxMKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50MTZBcnJheShpbywgQ291bnRCZywgbiAtPkJnLT5UYWJsZTE2KSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoU2l6ZU9mVGFnIDwgQ291bnRCZyAqIHNpemVvZihjbXNVSW50MTZOdW1iZXIpKSByZXR1cm4gTlVMTDsKICAgIFNpemVPZlRhZyAtPSBDb3VudEJnICogc2l6ZW9mKGNtc1VJbnQxNk51bWJlcik7CiAgICBpZiAoU2l6ZU9mVGFnID09IFVJTlRfTUFYKSByZXR1cm4gTlVMTDsKCiAgICAvLyBOb3cgY29tZXMgdGhlIHRleHQuIFRoZSBsZW5ndGggaXMgc3BlY2lmaWVkIGJ5IHRoZSB0YWcgc2l6ZQogICAgbiAtPkRlc2MgPSBjbXNNTFVhbGxvYyhzZWxmIC0+Q29udGV4dElELCAxKTsKICAgIGlmIChuIC0+RGVzYyA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBBU0NJSVN0cmluZyA9IChjaGFyKikgX2Ntc01hbGxvYyhzZWxmIC0+Q29udGV4dElELCBTaXplT2ZUYWcgKyAxKTsKICAgIGlmIChpbyAtPlJlYWQoaW8sIEFTQ0lJU3RyaW5nLCBzaXplb2YoY2hhciksIFNpemVPZlRhZykgIT0gU2l6ZU9mVGFnKSByZXR1cm4gTlVMTDsKICAgIEFTQ0lJU3RyaW5nW1NpemVPZlRhZ10gPSAwOwogICAgY21zTUxVc2V0QVNDSUkobiAtPkRlc2MsIGNtc05vTGFuZ3VhZ2UsIGNtc05vQ291bnRyeSwgQVNDSUlTdHJpbmcpOwogICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgQVNDSUlTdHJpbmcpOwoKICAgICpuSXRlbXMgPSAxOwogICAgcmV0dXJuICh2b2lkKikgbjsKfQoKc3RhdGljCmNtc0Jvb2wgIFR5cGVfVWNyQmdfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc1VjckJnKiBWYWx1ZSA9IChjbXNVY3JCZyopIFB0cjsKICAgIGNtc1VJbnQzMk51bWJlciBUZXh0U2l6ZTsKICAgIGNoYXIqIFRleHQ7CgogICAgLy8gRmlyc3QgY3VydmUgaXMgVW5kZXIgY29sb3IgcmVtb3ZhbAogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIFZhbHVlIC0+VWNyIC0+bkVudHJpZXMpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNkFycmF5KGlvLCBWYWx1ZSAtPlVjciAtPm5FbnRyaWVzLCBWYWx1ZSAtPlVjciAtPlRhYmxlMTYpKSByZXR1cm4gRkFMU0U7CgogICAgLy8gVGhlbiBibGFjayBnZW5lcmF0aW9uCiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgVmFsdWUgLT5CZyAtPm5FbnRyaWVzKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MTZBcnJheShpbywgVmFsdWUgLT5CZyAtPm5FbnRyaWVzLCBWYWx1ZSAtPkJnIC0+VGFibGUxNikpIHJldHVybiBGQUxTRTsKCiAgICAvLyBOb3cgY29tZXMgdGhlIHRleHQuIFRoZSBsZW5ndGggaXMgc3BlY2lmaWVkIGJ5IHRoZSB0YWcgc2l6ZQogICAgVGV4dFNpemUgPSBjbXNNTFVnZXRBU0NJSShWYWx1ZSAtPkRlc2MsIGNtc05vTGFuZ3VhZ2UsIGNtc05vQ291bnRyeSwgTlVMTCwgMCk7CiAgICBUZXh0ICAgICA9IChjaGFyKikgX2Ntc01hbGxvYyhzZWxmIC0+Q29udGV4dElELCBUZXh0U2l6ZSk7CiAgICBpZiAoY21zTUxVZ2V0QVNDSUkoVmFsdWUgLT5EZXNjLCBjbXNOb0xhbmd1YWdlLCBjbXNOb0NvdW50cnksIFRleHQsIFRleHRTaXplKSAhPSBUZXh0U2l6ZSkgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghaW8gLT5Xcml0ZShpbywgVGV4dFNpemUsIFRleHQpKSByZXR1cm4gRkFMU0U7CiAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBUZXh0KTsKCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7Cn0KCnN0YXRpYwp2b2lkKiBUeXBlX1VjckJnX0R1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgIGNtc1VjckJnKiBTcmMgPSAoY21zVWNyQmcqKSBQdHI7CiAgICBjbXNVY3JCZyogTmV3VWNyQmcgPSAoY21zVWNyQmcqKSBfY21zTWFsbG9jWmVybyhzZWxmIC0+Q29udGV4dElELCBzaXplb2YoY21zVWNyQmcpKTsKCiAgICBpZiAoTmV3VWNyQmcgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgTmV3VWNyQmcgLT5CZyAgID0gY21zRHVwVG9uZUN1cnZlKFNyYyAtPkJnKTsKICAgIE5ld1VjckJnIC0+VWNyICA9IGNtc0R1cFRvbmVDdXJ2ZShTcmMgLT5VY3IpOwogICAgTmV3VWNyQmcgLT5EZXNjID0gY21zTUxVZHVwKFNyYyAtPkRlc2MpOwoKICAgIHJldHVybiAodm9pZCopIE5ld1VjckJnOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7Cn0KCnN0YXRpYwp2b2lkIFR5cGVfVWNyQmdfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQgKlB0cikKewogICBjbXNVY3JCZyogU3JjID0gKGNtc1VjckJnKikgUHRyOwoKICAgaWYgKFNyYyAtPlVjcikgY21zRnJlZVRvbmVDdXJ2ZShTcmMgLT5VY3IpOwogICBpZiAoU3JjIC0+QmcpICBjbXNGcmVlVG9uZUN1cnZlKFNyYyAtPkJnKTsKICAgaWYgKFNyYyAtPkRlc2MpIGNtc01MVWZyZWUoU3JjIC0+RGVzYyk7CgogICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBQdHIpOwp9CgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUeXBlIGNtc1NpZ0NyZEluZm9UeXBlCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgovKgpUaGlzIHR5cGUgY29udGFpbnMgdGhlIFBvc3RTY3JpcHQgcHJvZHVjdCBuYW1lIHRvIHdoaWNoIHRoaXMgcHJvZmlsZSBjb3JyZXNwb25kcwphbmQgdGhlIG5hbWVzIG9mIHRoZSBjb21wYW5pb24gQ1JEcy4gUmVjYWxsIHRoYXQgYSBzaW5nbGUgcHJvZmlsZSBjYW4gZ2VuZXJhdGUKbXVsdGlwbGUgQ1JEcy4gSXQgaXMgaW1wbGVtZW50ZWQgYXMgYSBNTFUgYmVpbmcgdGhlIGxhbmd1YWdlIGNvZGUgIlBTIiBhbmQgdGhlbgpjb3VudHJ5IHZhcmllcyBmb3IgZWFjaCBlbGVtZW50OgoKICAgICAgICAgICAgICAgIG5tOiBQb3N0U2NyaXB0IHByb2R1Y3QgbmFtZQogICAgICAgICAgICAgICAgIzA6IFJlbmRlcmluZyBpbnRlbnQgMCBDUkQgbmFtZQogICAgICAgICAgICAgICAgIzE6IFJlbmRlcmluZyBpbnRlbnQgMSBDUkQgbmFtZQogICAgICAgICAgICAgICAgIzI6IFJlbmRlcmluZyBpbnRlbnQgMiBDUkQgbmFtZQogICAgICAgICAgICAgICAgIzM6IFJlbmRlcmluZyBpbnRlbnQgMyBDUkQgbmFtZQoqLwoKCgovLyBBdXhpbGlhciwgcmVhZCBhbiBzdHJpbmcgc3BlY2lmaWVkIGFzIGNvdW50ICsgc3RyaW5nCnN0YXRpYwpjbXNCb29sICBSZWFkQ291bnRBbmRTdGluZyhzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc01MVSogbWx1LCBjbXNVSW50MzJOdW1iZXIqIFNpemVPZlRhZywgY29uc3QgY2hhciogU2VjdGlvbikKewogICAgY21zVUludDMyTnVtYmVyIENvdW50OwogICAgY2hhciogVGV4dDsKCiAgICBpZiAoKlNpemVPZlRhZyA8IHNpemVvZihjbXNVSW50MzJOdW1iZXIpKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJkNvdW50KSkgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChDb3VudCA+IFVJTlRfTUFYIC0gc2l6ZW9mKGNtc1VJbnQzMk51bWJlcikpIHJldHVybiBGQUxTRTsKICAgIGlmICgqU2l6ZU9mVGFnIDwgQ291bnQgKyBzaXplb2YoY21zVUludDMyTnVtYmVyKSkgcmV0dXJuIEZBTFNFOwoKICAgIFRleHQgICAgID0gKGNoYXIqKSBfY21zTWFsbG9jKHNlbGYgLT5Db250ZXh0SUQsIENvdW50KzEpOwogICAgaWYgKFRleHQgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChpbyAtPlJlYWQoaW8sIFRleHQsIHNpemVvZihjbXNVSW50OE51bWJlciksIENvdW50KSAhPSBDb3VudCkgewogICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFRleHQpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBUZXh0W0NvdW50XSA9IDA7CgogICAgY21zTUxVc2V0QVNDSUkobWx1LCAiUFMiLCBTZWN0aW9uLCBUZXh0KTsKICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFRleHQpOwoKICAgICpTaXplT2ZUYWcgLT0gKENvdW50ICsgc2l6ZW9mKGNtc1VJbnQzMk51bWJlcikpOwogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYwpjbXNCb29sICBXcml0ZUNvdW50QW5kU3Rpbmcoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNNTFUqIG1sdSwgY29uc3QgY2hhciogU2VjdGlvbikKewogY21zVUludDMyTnVtYmVyIFRleHRTaXplOwogY2hhciogVGV4dDsKCiAgICBUZXh0U2l6ZSA9IGNtc01MVWdldEFTQ0lJKG1sdSwgIlBTIiwgU2VjdGlvbiwgTlVMTCwgMCk7CiAgICBUZXh0ICAgICA9IChjaGFyKikgX2Ntc01hbGxvYyhzZWxmIC0+Q29udGV4dElELCBUZXh0U2l6ZSk7CgogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIFRleHRTaXplKSkgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChjbXNNTFVnZXRBU0NJSShtbHUsICJQUyIsIFNlY3Rpb24sIFRleHQsIFRleHRTaXplKSA9PSAwKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKCFpbyAtPldyaXRlKGlvLCBUZXh0U2l6ZSwgVGV4dCkpIHJldHVybiBGQUxTRTsKICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFRleHQpOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMKdm9pZCAqVHlwZV9DcmRJbmZvX1JlYWQoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNVSW50MzJOdW1iZXIqIG5JdGVtcywgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY21zTUxVKiBtbHUgPSBjbXNNTFVhbGxvYyhzZWxmIC0+Q29udGV4dElELCA1KTsKCiAgICAqbkl0ZW1zID0gMDsKICAgIGlmICghUmVhZENvdW50QW5kU3Rpbmcoc2VsZiwgaW8sIG1sdSwgJlNpemVPZlRhZywgIm5tIikpIGdvdG8gRXJyb3I7CiAgICBpZiAoIVJlYWRDb3VudEFuZFN0aW5nKHNlbGYsIGlvLCBtbHUsICZTaXplT2ZUYWcsICIjMCIpKSBnb3RvIEVycm9yOwogICAgaWYgKCFSZWFkQ291bnRBbmRTdGluZyhzZWxmLCBpbywgbWx1LCAmU2l6ZU9mVGFnLCAiIzEiKSkgZ290byBFcnJvcjsKICAgIGlmICghUmVhZENvdW50QW5kU3Rpbmcoc2VsZiwgaW8sIG1sdSwgJlNpemVPZlRhZywgIiMyIikpIGdvdG8gRXJyb3I7CiAgICBpZiAoIVJlYWRDb3VudEFuZFN0aW5nKHNlbGYsIGlvLCBtbHUsICZTaXplT2ZUYWcsICIjMyIpKSBnb3RvIEVycm9yOwoKICAgICpuSXRlbXMgPSAxOwogICAgcmV0dXJuICh2b2lkKikgbWx1OwoKRXJyb3I6CiAgICBjbXNNTFVmcmVlKG1sdSk7CiAgICByZXR1cm4gTlVMTDsKCn0KCnN0YXRpYwpjbXNCb29sICBUeXBlX0NyZEluZm9fV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKCiAgICBjbXNNTFUqIG1sdSA9IChjbXNNTFUqKSBQdHI7CgogICAgaWYgKCFXcml0ZUNvdW50QW5kU3Rpbmcoc2VsZiwgaW8sIG1sdSwgIm5tIikpIGdvdG8gRXJyb3I7CiAgICBpZiAoIVdyaXRlQ291bnRBbmRTdGluZyhzZWxmLCBpbywgbWx1LCAiIzAiKSkgZ290byBFcnJvcjsKICAgIGlmICghV3JpdGVDb3VudEFuZFN0aW5nKHNlbGYsIGlvLCBtbHUsICIjMSIpKSBnb3RvIEVycm9yOwogICAgaWYgKCFXcml0ZUNvdW50QW5kU3Rpbmcoc2VsZiwgaW8sIG1sdSwgIiMyIikpIGdvdG8gRXJyb3I7CiAgICBpZiAoIVdyaXRlQ291bnRBbmRTdGluZyhzZWxmLCBpbywgbWx1LCAiIzMiKSkgZ290byBFcnJvcjsKCiAgICByZXR1cm4gVFJVRTsKCkVycm9yOgogICAgcmV0dXJuIEZBTFNFOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKfQoKCnN0YXRpYwp2b2lkKiBUeXBlX0NyZEluZm9fRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCAqUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICAgcmV0dXJuICh2b2lkKikgY21zTUxVZHVwKChjbXNNTFUqKSBQdHIpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgpzdGF0aWMKdm9pZCBUeXBlX0NyZEluZm9fRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQgKlB0cikKewogICAgY21zTUxVZnJlZSgoY21zTUxVKikgUHRyKTsKICAgIHJldHVybjsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUeXBlIGNtc1NpZ1NjcmVlbmluZ1R5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8KLy9UaGUgc2NyZWVuaW5nVHlwZSBkZXNjcmliZXMgdmFyaW91cyBzY3JlZW5pbmcgcGFyYW1ldGVycyBpbmNsdWRpbmcgc2NyZWVuCi8vZnJlcXVlbmN5LCBzY3JlZW5pbmcgYW5nbGUsIGFuZCBzcG90IHNoYXBlLgoKc3RhdGljCnZvaWQgKlR5cGVfU2NyZWVuaW5nX1JlYWQoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNVSW50MzJOdW1iZXIqIG5JdGVtcywgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY21zU2NyZWVuaW5nKiBzYyA9IE5VTEw7CiAgICBjbXNVSW50MzJOdW1iZXIgaTsKCiAgICBzYyA9IChjbXNTY3JlZW5pbmcqKSBfY21zTWFsbG9jWmVybyhzZWxmIC0+Q29udGV4dElELCBzaXplb2YoY21zU2NyZWVuaW5nKSk7CiAgICBpZiAoc2MgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgKm5JdGVtcyA9IDA7CgogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJnNjIC0+RmxhZykpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmc2MgLT5uQ2hhbm5lbHMpKSBnb3RvIEVycm9yOwoKICAgIGlmIChzYyAtPm5DaGFubmVscyA+IGNtc01BWENIQU5ORUxTIC0gMSkKICAgICAgICBzYyAtPm5DaGFubmVscyA9IGNtc01BWENIQU5ORUxTIC0gMTsKCiAgICBmb3IgKGk9MDsgaSA8IHNjIC0+bkNoYW5uZWxzOyBpKyspIHsKCiAgICAgICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJnNjIC0+Q2hhbm5lbHNbaV0uRnJlcXVlbmN5KSkgZ290byBFcnJvcjsKICAgICAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAmc2MgLT5DaGFubmVsc1tpXS5TY3JlZW5BbmdsZSkpIGdvdG8gRXJyb3I7CiAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJnNjIC0+Q2hhbm5lbHNbaV0uU3BvdFNoYXBlKSkgZ290byBFcnJvcjsKICAgIH0KCgogICAgKm5JdGVtcyA9IDE7CgogICAgcmV0dXJuICh2b2lkKikgc2M7CgpFcnJvcjoKICAgIGlmIChzYyAhPSBOVUxMKQogICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIHNjKTsKCiAgICByZXR1cm4gTlVMTDsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKFNpemVPZlRhZyk7Cn0KCgpzdGF0aWMKY21zQm9vbCBUeXBlX1NjcmVlbmluZ19Xcml0ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIHZvaWQqIFB0ciwgY21zVUludDMyTnVtYmVyIG5JdGVtcykKewogICAgY21zU2NyZWVuaW5nKiBzYyA9IChjbXNTY3JlZW5pbmcqICkgUHRyOwogICAgY21zVUludDMyTnVtYmVyIGk7CgogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIHNjIC0+RmxhZykpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBzYyAtPm5DaGFubmVscykpIHJldHVybiBGQUxTRTsKCiAgICBmb3IgKGk9MDsgaSA8IHNjIC0+bkNoYW5uZWxzOyBpKyspIHsKCiAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIHNjIC0+Q2hhbm5lbHNbaV0uRnJlcXVlbmN5KSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCBzYyAtPkNoYW5uZWxzW2ldLlNjcmVlbkFuZ2xlKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBzYyAtPkNoYW5uZWxzW2ldLlNwb3RTaGFwZSkpIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKc3RhdGljCnZvaWQqIFR5cGVfU2NyZWVuaW5nX0R1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgcmV0dXJuIF9jbXNEdXBNZW0oc2VsZiAtPkNvbnRleHRJRCwgUHRyLCBzaXplb2YoY21zU2NyZWVuaW5nKSk7CgogICBjbXNVTlVTRURfUEFSQU1FVEVSKG4pOwp9CgoKc3RhdGljCnZvaWQgVHlwZV9TY3JlZW5pbmdfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQqIFB0cikKewogICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBQdHIpOwp9CgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUeXBlIGNtc1NpZ1ZpZXdpbmdDb25kaXRpb25zVHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovL1RoaXMgdHlwZSByZXByZXNlbnRzIGEgc2V0IG9mIHZpZXdpbmcgY29uZGl0aW9uIHBhcmFtZXRlcnMgaW5jbHVkaW5nOgovL0NJRSCSYWJzb2x1dGU/aWxsdW1pbmFudCB3aGl0ZSBwb2ludCB0cmlzdGltdWx1cyB2YWx1ZXMgYW5kIENJRSCSYWJzb2x1dGU/Ly9zdXJyb3VuZCB0cmlzdGltdWx1cyB2YWx1ZXMuCgpzdGF0aWMKdm9pZCAqVHlwZV9WaWV3aW5nQ29uZGl0aW9uc19SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc0lDQ1ZpZXdpbmdDb25kaXRpb25zKiB2YyA9IE5VTEw7CgogICAgdmMgPSAoY21zSUNDVmlld2luZ0NvbmRpdGlvbnMqKSBfY21zTWFsbG9jWmVybyhzZWxmIC0+Q29udGV4dElELCBzaXplb2YoY21zSUNDVmlld2luZ0NvbmRpdGlvbnMpKTsKICAgIGlmICh2YyA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICAqbkl0ZW1zID0gMDsKCiAgICBpZiAoIV9jbXNSZWFkWFlaTnVtYmVyKGlvLCAmdmMgLT5JbGx1bWluYW50WFlaKSkgZ290byBFcnJvcjsKICAgIGlmICghX2Ntc1JlYWRYWVpOdW1iZXIoaW8sICZ2YyAtPlN1cnJvdW5kWFlaKSkgZ290byBFcnJvcjsKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZ2YyAtPklsbHVtaW5hbnRUeXBlKSkgZ290byBFcnJvcjsKCiAgICAqbkl0ZW1zID0gMTsKCiAgICByZXR1cm4gKHZvaWQqKSB2YzsKCkVycm9yOgogICAgaWYgKHZjICE9IE5VTEwpCiAgICAgICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgdmMpOwoKICAgIHJldHVybiBOVUxMOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoU2l6ZU9mVGFnKTsKfQoKCnN0YXRpYwpjbXNCb29sIFR5cGVfVmlld2luZ0NvbmRpdGlvbnNfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc0lDQ1ZpZXdpbmdDb25kaXRpb25zKiBzYyA9IChjbXNJQ0NWaWV3aW5nQ29uZGl0aW9ucyogKSBQdHI7CgogICAgaWYgKCFfY21zV3JpdGVYWVpOdW1iZXIoaW8sICZzYyAtPklsbHVtaW5hbnRYWVopKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVhZWk51bWJlcihpbywgJnNjIC0+U3Vycm91bmRYWVopKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgc2MgLT5JbGx1bWluYW50VHlwZSkpIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKc3RhdGljCnZvaWQqIFR5cGVfVmlld2luZ0NvbmRpdGlvbnNfRHVwKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY29uc3Qgdm9pZCAqUHRyLCBjbXNVSW50MzJOdW1iZXIgbikKewogICByZXR1cm4gX2Ntc0R1cE1lbShzZWxmIC0+Q29udGV4dElELCBQdHIsIHNpemVvZihjbXNTY3JlZW5pbmcpKTsKCiAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7Cn0KCgpzdGF0aWMKdm9pZCBUeXBlX1ZpZXdpbmdDb25kaXRpb25zX0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgUHRyKTsKfQoKCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFR5cGUgY21zU2lnTXVsdGlQcm9jZXNzRWxlbWVudFR5cGUKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCgpzdGF0aWMKdm9pZCogR2VuZXJpY01QRWR1cChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNvbnN0IHZvaWQgKlB0ciwgY21zVUludDMyTnVtYmVyIG4pCnsKICAgIHJldHVybiAodm9pZCopIGNtc1N0YWdlRHVwKChjbXNTdGFnZSopIFB0cik7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoc2VsZik7Cn0KCnN0YXRpYwp2b2lkIEdlbmVyaWNNUEVmcmVlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgdm9pZCAqUHRyKQp7CiAgICBjbXNTdGFnZUZyZWUoKGNtc1N0YWdlKikgUHRyKTsKICAgIHJldHVybjsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgovLyBFYWNoIGN1cnZlIGlzIHN0b3JlZCBpbiBvbmUgb3IgbW9yZSBjdXJ2ZSBzZWdtZW50cywgd2l0aCBicmVhay1wb2ludHMgc3BlY2lmaWVkIGJldHdlZW4gY3VydmUgc2VnbWVudHMuCi8vIFRoZSBmaXJzdCBjdXJ2ZSBzZWdtZW50IGFsd2F5cyBzdGFydHMgYXQglkluZmluaXR5LCBhbmQgdGhlIGxhc3QgY3VydmUgc2VnbWVudCBhbHdheXMgZW5kcyBhdCArSW5maW5pdHkuIFRoZQovLyBmaXJzdCBhbmQgbGFzdCBjdXJ2ZSBzZWdtZW50cyBzaGFsbCBiZSBzcGVjaWZpZWQgaW4gdGVybXMgb2YgYSBmb3JtdWxhLCB3aGVyZWFzIHRoZSBvdGhlciBzZWdtZW50cyBzaGFsbCBiZQovLyBzcGVjaWZpZWQgZWl0aGVyIGluIHRlcm1zIG9mIGEgZm9ybXVsYSwgb3IgYnkgYSBzYW1wbGVkIGN1cnZlLgoKCi8vIFJlYWQgYW4gZW1iZWRkZWQgc2VnbWVudGVkIGN1cnZlCnN0YXRpYwpjbXNUb25lQ3VydmUqIFJlYWRTZWdtZW50ZWRDdXJ2ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8pCnsKICAgIGNtc0N1cnZlU2VnU2lnbmF0dXJlIEVsZW1lbnRTaWc7CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgajsKICAgIGNtc1VJbnQxNk51bWJlciBuU2VnbWVudHM7CiAgICBjbXNDdXJ2ZVNlZ21lbnQqICBTZWdtZW50czsKICAgIGNtc1RvbmVDdXJ2ZSogQ3VydmU7CiAgICBjbXNGbG9hdDMyTnVtYmVyIFByZXZCcmVhayA9IC0xRTIyRjsgICAgLy8gLSBpbmZpbml0ZQoKICAgIC8vIFRha2Ugc2lnbmF0dXJlIGFuZCBjaGFubmVscyBmb3IgZWFjaCBlbGVtZW50LgogICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sIChjbXNVSW50MzJOdW1iZXIqKSAmRWxlbWVudFNpZykpIHJldHVybiBOVUxMOwoKICAgICAvLyBUaGF0IHNob3VsZCBiZSBhIHNlZ21lbnRlZCBjdXJ2ZQogICAgIGlmIChFbGVtZW50U2lnICE9IGNtc1NpZ1NlZ21lbnRlZEN1cnZlKSByZXR1cm4gTlVMTDsKCiAgICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgTlVMTCkpIHJldHVybiBOVUxMOwogICAgIGlmICghX2Ntc1JlYWRVSW50MTZOdW1iZXIoaW8sICZuU2VnbWVudHMpKSByZXR1cm4gTlVMTDsKICAgICBpZiAoIV9jbXNSZWFkVUludDE2TnVtYmVyKGlvLCBOVUxMKSkgcmV0dXJuIE5VTEw7CgogICAgIGlmIChuU2VnbWVudHMgPCAxKSByZXR1cm4gTlVMTDsKICAgICBTZWdtZW50cyA9IChjbXNDdXJ2ZVNlZ21lbnQqKSBfY21zQ2FsbG9jKHNlbGYgLT5Db250ZXh0SUQsIG5TZWdtZW50cywgc2l6ZW9mKGNtc0N1cnZlU2VnbWVudCkpOwogICAgIGlmIChTZWdtZW50cyA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICAgLy8gUmVhZCBicmVha3BvaW50cwogICAgIGZvciAoaT0wOyBpIDwgKGNtc1VJbnQzMk51bWJlcikgblNlZ21lbnRzIC0gMTsgaSsrKSB7CgogICAgICAgICBTZWdtZW50c1tpXS54MCA9IFByZXZCcmVhazsKICAgICAgICAgaWYgKCFfY21zUmVhZEZsb2F0MzJOdW1iZXIoaW8sICZTZWdtZW50c1tpXS54MSkpIGdvdG8gRXJyb3I7CiAgICAgICAgIFByZXZCcmVhayA9IFNlZ21lbnRzW2ldLngxOwogICAgIH0KCiAgICAgU2VnbWVudHNbblNlZ21lbnRzLTFdLngwID0gUHJldkJyZWFrOwogICAgIFNlZ21lbnRzW25TZWdtZW50cy0xXS54MSA9IDFFMjJGOyAgICAgLy8gQSBiaWcgY21zRmxvYXQzMk51bWJlciBudW1iZXIKCiAgICAgLy8gUmVhZCBzZWdtZW50cwogICAgIGZvciAoaT0wOyBpIDwgblNlZ21lbnRzOyBpKyspIHsKCiAgICAgICAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAoY21zVUludDMyTnVtYmVyKikgJkVsZW1lbnRTaWcpKSBnb3RvIEVycm9yOwogICAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgTlVMTCkpIGdvdG8gRXJyb3I7CgogICAgICAgICAgIHN3aXRjaCAoRWxlbWVudFNpZykgewoKICAgICAgICAgICAgY2FzZSBjbXNTaWdGb3JtdWxhQ3VydmVTZWc6IHsKCiAgICAgICAgICAgICAgICBjbXNVSW50MTZOdW1iZXIgVHlwZTsKICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBQYXJhbXNCeVR5cGVbXSA9IHs0LCA1LCA1IH07CgogICAgICAgICAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJlR5cGUpKSBnb3RvIEVycm9yOwogICAgICAgICAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgTlVMTCkpIGdvdG8gRXJyb3I7CgogICAgICAgICAgICAgICAgU2VnbWVudHNbaV0uVHlwZSA9IFR5cGUgKyA2OwogICAgICAgICAgICAgICAgaWYgKFR5cGUgPiAyKSBnb3RvIEVycm9yOwoKICAgICAgICAgICAgICAgIGZvciAoaj0wOyBqIDwgUGFyYW1zQnlUeXBlW1R5cGVdOyBqKyspIHsKCiAgICAgICAgICAgICAgICAgICAgY21zRmxvYXQzMk51bWJlciBmOwogICAgICAgICAgICAgICAgICAgIGlmICghX2Ntc1JlYWRGbG9hdDMyTnVtYmVyKGlvLCAmZikpIGdvdG8gRXJyb3I7CiAgICAgICAgICAgICAgICAgICAgU2VnbWVudHNbaV0uUGFyYW1zW2pdID0gZjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKCiAgICAgICAgICAgIGNhc2UgY21zU2lnU2FtcGxlZEN1cnZlU2VnOiB7CiAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgQ291bnQ7CgogICAgICAgICAgICAgICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJkNvdW50KSkgcmV0dXJuIE5VTEw7CgogICAgICAgICAgICAgICAgU2VnbWVudHNbaV0ubkdyaWRQb2ludHMgPSBDb3VudDsKICAgICAgICAgICAgICAgIFNlZ21lbnRzW2ldLlNhbXBsZWRQb2ludHMgPSAoY21zRmxvYXQzMk51bWJlciopIF9jbXNDYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgQ291bnQsIHNpemVvZihjbXNGbG9hdDMyTnVtYmVyKSk7CiAgICAgICAgICAgICAgICBpZiAoU2VnbWVudHNbaV0uU2FtcGxlZFBvaW50cyA9PSBOVUxMKSBnb3RvIEVycm9yOwoKICAgICAgICAgICAgICAgIGZvciAoaj0wOyBqIDwgQ291bnQ7IGorKykgewogICAgICAgICAgICAgICAgICAgIGlmICghX2Ntc1JlYWRGbG9hdDMyTnVtYmVyKGlvLCAmU2VnbWVudHNbaV0uU2FtcGxlZFBvaW50c1tqXSkpIGdvdG8gRXJyb3I7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjaGFyIFN0cmluZ1s1XTsKCiAgICAgICAgICAgICAgICBfY21zVGFnU2lnbmF0dXJlMlN0cmluZyhTdHJpbmcsIChjbXNUYWdTaWduYXR1cmUpIEVsZW1lbnRTaWcpOwogICAgICAgICAgICAgICAgY21zU2lnbmFsRXJyb3Ioc2VsZi0+Q29udGV4dElELCBjbXNFUlJPUl9VTktOT1dOX0VYVEVOU0lPTiwgIlVua25vd24gY3VydmUgZWxlbWVudCB0eXBlICclcycgZm91bmQuIiwgU3RyaW5nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwoKICAgICAgICAgfQogICAgIH0KCiAgICAgQ3VydmUgPSBjbXNCdWlsZFNlZ21lbnRlZFRvbmVDdXJ2ZShzZWxmIC0+Q29udGV4dElELCBuU2VnbWVudHMsIFNlZ21lbnRzKTsKCiAgICAgZm9yIChpPTA7IGkgPCBuU2VnbWVudHM7IGkrKykgewogICAgICAgICBpZiAoU2VnbWVudHNbaV0uU2FtcGxlZFBvaW50cykgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgU2VnbWVudHNbaV0uU2FtcGxlZFBvaW50cyk7CiAgICAgfQogICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFNlZ21lbnRzKTsKICAgICByZXR1cm4gQ3VydmU7CgpFcnJvcjoKICAgICBpZiAoU2VnbWVudHMpIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIFNlZ21lbnRzKTsKICAgICByZXR1cm4gTlVMTDsKfQoKCnN0YXRpYwpjbXNCb29sIFJlYWRNUEVDdXJ2ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgIGNtc0lPSEFORExFUiogaW8sCiAgICAgICAgICAgICAgICAgICAgIHZvaWQqIENhcmdvLAogICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgbiwKICAgICAgICAgICAgICAgICAgICAgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgICBjbXNUb25lQ3VydmUqKiBHYW1tYVRhYmxlcyA9ICggY21zVG9uZUN1cnZlKiopIENhcmdvOwoKICAgICAgR2FtbWFUYWJsZXNbbl0gPSBSZWFkU2VnbWVudGVkQ3VydmUoc2VsZiwgaW8pOwogICAgICByZXR1cm4gKEdhbW1hVGFibGVzW25dICE9IE5VTEwpOwoKICAgICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwp9CgpzdGF0aWMKdm9pZCAqVHlwZV9NUEVjdXJ2ZV9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc1N0YWdlKiBtcGUgPSBOVUxMOwogICAgY21zVUludDE2TnVtYmVyIElucHV0Q2hhbnMsIE91dHB1dENoYW5zOwogICAgY21zVUludDMyTnVtYmVyIGksIEJhc2VPZmZzZXQ7CiAgICBjbXNUb25lQ3VydmUqKiBHYW1tYVRhYmxlczsKCiAgICAqbkl0ZW1zID0gMDsKCiAgICAvLyBHZXQgYWN0dWFsIHBvc2l0aW9uIGFzIGEgYmFzaXMgZm9yIGVsZW1lbnQgb2Zmc2V0cwogICAgQmFzZU9mZnNldCA9IGlvIC0+VGVsbChpbykgLSBzaXplb2YoX2Ntc1RhZ0Jhc2UpOwoKICAgIGlmICghX2Ntc1JlYWRVSW50MTZOdW1iZXIoaW8sICZJbnB1dENoYW5zKSkgcmV0dXJuIE5VTEw7CiAgICBpZiAoIV9jbXNSZWFkVUludDE2TnVtYmVyKGlvLCAmT3V0cHV0Q2hhbnMpKSByZXR1cm4gTlVMTDsKCiAgICBpZiAoSW5wdXRDaGFucyAhPSBPdXRwdXRDaGFucykgcmV0dXJuIE5VTEw7CgogICAgR2FtbWFUYWJsZXMgPSAoY21zVG9uZUN1cnZlKiopIF9jbXNDYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgSW5wdXRDaGFucywgc2l6ZW9mKGNtc1RvbmVDdXJ2ZSopKTsKICAgIGlmIChHYW1tYVRhYmxlcyA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBpZiAoUmVhZFBvc2l0aW9uVGFibGUoc2VsZiwgaW8sIElucHV0Q2hhbnMsIEJhc2VPZmZzZXQsIEdhbW1hVGFibGVzLCBSZWFkTVBFQ3VydmUpKSB7CgogICAgICAgIG1wZSA9IGNtc1N0YWdlQWxsb2NUb25lQ3VydmVzKHNlbGYgLT5Db250ZXh0SUQsIElucHV0Q2hhbnMsIEdhbW1hVGFibGVzKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIG1wZSA9IE5VTEw7CiAgICB9CgogICAgZm9yIChpPTA7IGkgPCBJbnB1dENoYW5zOyBpKyspIHsKICAgICAgICBpZiAoR2FtbWFUYWJsZXNbaV0pIGNtc0ZyZWVUb25lQ3VydmUoR2FtbWFUYWJsZXNbaV0pOwogICAgfQoKICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIEdhbW1hVGFibGVzKTsKICAgICpuSXRlbXMgPSAobXBlICE9IE5VTEwpID8gMSA6IDA7CiAgICByZXR1cm4gbXBlOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoU2l6ZU9mVGFnKTsKfQoKCi8vIFdyaXRlIGEgc2luZ2xlIHNlZ21lbnRlZCBjdXJ2ZS4gTk8gQ0hFQ0sgSVMgUEVSRk9STUVEIE9OIFZBTElESVRZCnN0YXRpYwpjbXNCb29sIFdyaXRlU2VnbWVudGVkQ3VydmUoY21zSU9IQU5ETEVSKiBpbywgY21zVG9uZUN1cnZlKiBnKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgajsKICAgIGNtc0N1cnZlU2VnbWVudCogU2VnbWVudHMgPSBnIC0+U2VnbWVudHM7CiAgICBjbXNVSW50MzJOdW1iZXIgblNlZ21lbnRzID0gZyAtPm5TZWdtZW50czsKCiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgY21zU2lnU2VnbWVudGVkQ3VydmUpKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIDApKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zV3JpdGVVSW50MTZOdW1iZXIoaW8sIChjbXNVSW50MTZOdW1iZXIpIG5TZWdtZW50cykpIGdvdG8gRXJyb3I7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgMCkpIGdvdG8gRXJyb3I7CgogICAgLy8gV3JpdGUgdGhlIGJyZWFrLXBvaW50cwogICAgZm9yIChpPTA7IGkgPCBuU2VnbWVudHMgLSAxOyBpKyspIHsKICAgICAgICBpZiAoIV9jbXNXcml0ZUZsb2F0MzJOdW1iZXIoaW8sIFNlZ21lbnRzW2ldLngxKSkgZ290byBFcnJvcjsKICAgIH0KCiAgICAvLyBXcml0ZSB0aGUgc2VnbWVudHMKICAgIGZvciAoaT0wOyBpIDwgZyAtPm5TZWdtZW50czsgaSsrKSB7CgogICAgICAgIGNtc0N1cnZlU2VnbWVudCogQWN0dWFsU2VnID0gU2VnbWVudHMgKyBpOwoKICAgICAgICBpZiAoQWN0dWFsU2VnIC0+IFR5cGUgPT0gMCkgewoKICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHNhbXBsZWQgY3VydmUKICAgICAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIChjbXNVSW50MzJOdW1iZXIpIGNtc1NpZ1NhbXBsZWRDdXJ2ZVNlZykpIGdvdG8gRXJyb3I7CiAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCAwKSkgZ290byBFcnJvcjsKICAgICAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIEFjdHVhbFNlZyAtPiBuR3JpZFBvaW50cykpIGdvdG8gRXJyb3I7CgogICAgICAgICAgICBmb3IgKGo9MDsgaiA8IGcgLT5TZWdtZW50c1tpXS5uR3JpZFBvaW50czsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoIV9jbXNXcml0ZUZsb2F0MzJOdW1iZXIoaW8sIEFjdHVhbFNlZyAtPiBTYW1wbGVkUG9pbnRzW2pdKSkgZ290byBFcnJvcjsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGludCBUeXBlOwogICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgUGFyYW1zQnlUeXBlW10gPSB7IDQsIDUsIDUgfTsKCiAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBmb3JtdWxhLWJhc2VkCiAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCAoY21zVUludDMyTnVtYmVyKSBjbXNTaWdGb3JtdWxhQ3VydmVTZWcpKSBnb3RvIEVycm9yOwogICAgICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgMCkpIGdvdG8gRXJyb3I7CgogICAgICAgICAgICAvLyBXZSBvbmx5IGFsbG93IDEsIDIgYW5kIDMgYXMgdHlwZXMKICAgICAgICAgICAgVHlwZSA9IEFjdHVhbFNlZyAtPlR5cGUgLSA2OwogICAgICAgICAgICBpZiAoVHlwZSA+IDIgfHwgVHlwZSA8IDApIGdvdG8gRXJyb3I7CgogICAgICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgKGNtc1VJbnQxNk51bWJlcikgVHlwZSkpIGdvdG8gRXJyb3I7CiAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlVUludDE2TnVtYmVyKGlvLCAwKSkgZ290byBFcnJvcjsKCiAgICAgICAgICAgIGZvciAoaj0wOyBqIDwgUGFyYW1zQnlUeXBlW1R5cGVdOyBqKyspIHsKICAgICAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlRmxvYXQzMk51bWJlcihpbywgKGNtc0Zsb2F0MzJOdW1iZXIpIEFjdHVhbFNlZyAtPlBhcmFtc1tqXSkpIGdvdG8gRXJyb3I7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIEl0IHNlZW1zIHRoZXJlIGlzIG5vIG5lZWQgdG8gYWxpZ24uIENvZGUgaXMgaGVyZSwgYW5kIGZvciBzYWZldHkgY29tbWVudGVkIG91dAogICAgICAgIC8vIGlmICghX2Ntc1dyaXRlQWxpZ25tZW50KGlvKSkgZ290byBFcnJvcjsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKCkVycm9yOgogICAgcmV0dXJuIEZBTFNFOwp9CgoKc3RhdGljCmNtc0Jvb2wgV3JpdGVNUEVDdXJ2ZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICBjbXNJT0hBTkRMRVIqIGlvLAogICAgICAgICAgICAgICAgICAgICAgdm9pZCogQ2FyZ28sCiAgICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgbiwKICAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIF9jbXNTdGFnZVRvbmVDdXJ2ZXNEYXRhKiBDdXJ2ZXMgID0gKF9jbXNTdGFnZVRvbmVDdXJ2ZXNEYXRhKikgQ2FyZ287CgogICAgcmV0dXJuIFdyaXRlU2VnbWVudGVkQ3VydmUoaW8sIEN1cnZlcyAtPlRoZUN1cnZlc1tuXSk7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKfQoKLy8gV3JpdGUgYSBjdXJ2ZSwgY2hlY2tpbmcgZmlyc3QgZm9yIHZhbGlkaXR5CnN0YXRpYwpjbXNCb29sICBUeXBlX01QRWN1cnZlX1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgQmFzZU9mZnNldDsKICAgIGNtc1N0YWdlKiBtcGUgPSAoY21zU3RhZ2UqKSBQdHI7CiAgICBfY21zU3RhZ2VUb25lQ3VydmVzRGF0YSogQ3VydmVzID0gKF9jbXNTdGFnZVRvbmVDdXJ2ZXNEYXRhKikgbXBlIC0+RGF0YTsKCiAgICBCYXNlT2Zmc2V0ID0gaW8gLT5UZWxsKGlvKSAtIHNpemVvZihfY21zVGFnQmFzZSk7CgogICAgLy8gV3JpdGUgdGhlIGhlYWRlci4gU2luY2UgdGhvc2UgYXJlIGN1cnZlcywgaW5wdXQgYW5kIG91dHB1dCBjaGFubmVscyBhcmUgc2FtZQogICAgaWYgKCFfY21zV3JpdGVVSW50MTZOdW1iZXIoaW8sIChjbXNVSW50MTZOdW1iZXIpIG1wZSAtPklucHV0Q2hhbm5lbHMpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgKGNtc1VJbnQxNk51bWJlcikgbXBlIC0+SW5wdXRDaGFubmVscykpIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIVdyaXRlUG9zaXRpb25UYWJsZShzZWxmLCBpbywgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtcGUgLT5JbnB1dENoYW5uZWxzLCBCYXNlT2Zmc2V0LCBDdXJ2ZXMsIFdyaXRlTVBFQ3VydmUpKSByZXR1cm4gRkFMU0U7CgoKICAgIHJldHVybiBUUlVFOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKfQoKCgovLyBUaGUgbWF0cml4IGlzIG9yZ2FuaXplZCBhcyBhbiBhcnJheSBvZiBQeFErUSBlbGVtZW50cywgd2hlcmUgUCBpcyB0aGUgbnVtYmVyIG9mIGlucHV0IGNoYW5uZWxzIHRvIHRoZQovLyBtYXRyaXgsIGFuZCBRIGlzIHRoZSBudW1iZXIgb2Ygb3V0cHV0IGNoYW5uZWxzLiBUaGUgbWF0cml4IGVsZW1lbnRzIGFyZSBlYWNoIGZsb2F0MzJOdW1iZXJzLiBUaGUgYXJyYXkKLy8gaXMgb3JnYW5pemVkIGFzIGZvbGxvd3M6Ci8vIGFycmF5ID0gW2UxMSwgZTEyLCA/IGUxUCwgZTIxLCBlMjIsID8gZTJQLCA/IGVRMSwgZVEyLCA/IGVRUCwgZTEsIGUyLCA/IGVRXQoKc3RhdGljCnZvaWQgKlR5cGVfTVBFbWF0cml4X1JlYWQoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCBjbXNVSW50MzJOdW1iZXIqIG5JdGVtcywgY21zVUludDMyTnVtYmVyIFNpemVPZlRhZykKewogICAgY21zU3RhZ2UqIG1wZTsKICAgIGNtc1VJbnQxNk51bWJlciAgIElucHV0Q2hhbnMsIE91dHB1dENoYW5zOwogICAgY21zVUludDMyTnVtYmVyICAgbkVsZW1zLCBpOwogICAgY21zRmxvYXQ2NE51bWJlciogTWF0cml4OwogICAgY21zRmxvYXQ2NE51bWJlciogT2Zmc2V0czsKCiAgICBpZiAoIV9jbXNSZWFkVUludDE2TnVtYmVyKGlvLCAmSW5wdXRDaGFucykpIHJldHVybiBOVUxMOwogICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJk91dHB1dENoYW5zKSkgcmV0dXJuIE5VTEw7CgoKICAgIG5FbGVtcyA9IElucHV0Q2hhbnMgKiBPdXRwdXRDaGFuczsKCiAgICAvLyBJbnB1dCBhbmQgb3V0cHV0IGNoYW5zIG1heSBiZSBBTlkgKHVwIHRvIDB4ZmZmZikKICAgIE1hdHJpeCA9IChjbXNGbG9hdDY0TnVtYmVyKikgX2Ntc0NhbGxvYyhzZWxmIC0+Q29udGV4dElELCBuRWxlbXMsIHNpemVvZihjbXNGbG9hdDY0TnVtYmVyKSk7CiAgICBpZiAoTWF0cml4ID09IE5VTEwpIHJldHVybiBOVUxMOwoKICAgIE9mZnNldHMgPSAoY21zRmxvYXQ2NE51bWJlciopIF9jbXNDYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgT3V0cHV0Q2hhbnMsIHNpemVvZihjbXNGbG9hdDY0TnVtYmVyKSk7CiAgICBpZiAoT2Zmc2V0cyA9PSBOVUxMKSB7CgogICAgICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIE1hdHJpeCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgZm9yIChpPTA7IGkgPCBuRWxlbXM7IGkrKykgewoKICAgICAgICBjbXNGbG9hdDMyTnVtYmVyIHY7CgogICAgICAgIGlmICghX2Ntc1JlYWRGbG9hdDMyTnVtYmVyKGlvLCAmdikpIHJldHVybiBOVUxMOwogICAgICAgIE1hdHJpeFtpXSA9IHY7CiAgICB9CgoKICAgIGZvciAoaT0wOyBpIDwgT3V0cHV0Q2hhbnM7IGkrKykgewoKICAgICAgICBjbXNGbG9hdDMyTnVtYmVyIHY7CgogICAgICAgIGlmICghX2Ntc1JlYWRGbG9hdDMyTnVtYmVyKGlvLCAmdikpIHJldHVybiBOVUxMOwogICAgICAgIE9mZnNldHNbaV0gPSB2OwogICAgfQoKCiAgICBtcGUgPSBjbXNTdGFnZUFsbG9jTWF0cml4KHNlbGYgLT5Db250ZXh0SUQsIE91dHB1dENoYW5zLCBJbnB1dENoYW5zLCBNYXRyaXgsIE9mZnNldHMpOwogICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgTWF0cml4KTsKICAgIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIE9mZnNldHMpOwoKICAgICpuSXRlbXMgPSAxOwoKICAgIHJldHVybiBtcGU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwp9CgpzdGF0aWMKY21zQm9vbCAgVHlwZV9NUEVtYXRyaXhfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc1VJbnQzMk51bWJlciBpLCBuRWxlbXM7CiAgICBjbXNTdGFnZSogbXBlID0gKGNtc1N0YWdlKikgUHRyOwogICAgX2Ntc1N0YWdlTWF0cml4RGF0YSogTWF0cml4ID0gKF9jbXNTdGFnZU1hdHJpeERhdGEqKSBtcGUgLT5EYXRhOwoKICAgIGlmICghX2Ntc1dyaXRlVUludDE2TnVtYmVyKGlvLCAoY21zVUludDE2TnVtYmVyKSBtcGUgLT5JbnB1dENoYW5uZWxzKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zV3JpdGVVSW50MTZOdW1iZXIoaW8sIChjbXNVSW50MTZOdW1iZXIpIG1wZSAtPk91dHB1dENoYW5uZWxzKSkgcmV0dXJuIEZBTFNFOwoKICAgIG5FbGVtcyA9IG1wZSAtPklucHV0Q2hhbm5lbHMgKiBtcGUgLT5PdXRwdXRDaGFubmVsczsKCiAgICBmb3IgKGk9MDsgaSA8IG5FbGVtczsgaSsrKSB7CiAgICAgICAgaWYgKCFfY21zV3JpdGVGbG9hdDMyTnVtYmVyKGlvLCAoY21zRmxvYXQzMk51bWJlcikgTWF0cml4LT5Eb3VibGVbaV0pKSByZXR1cm4gRkFMU0U7CiAgICB9CgoKICAgIGZvciAoaT0wOyBpIDwgbXBlIC0+T3V0cHV0Q2hhbm5lbHM7IGkrKykgewoKICAgICAgICBpZiAoTWF0cml4IC0+T2Zmc2V0ID09IE5VTEwpIHsKCiAgICAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlRmxvYXQzMk51bWJlcihpbywgMCkpIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlRmxvYXQzMk51bWJlcihpbywgKGNtc0Zsb2F0MzJOdW1iZXIpIE1hdHJpeC0+T2Zmc2V0W2ldKSkgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKCnN0YXRpYwp2b2lkICpUeXBlX01QRWNsdXRfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIGNtc0lPSEFORExFUiogaW8sIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLCBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNTdGFnZSogbXBlID0gTlVMTDsKICAgIGNtc1VJbnQxNk51bWJlciBJbnB1dENoYW5zLCBPdXRwdXRDaGFuczsKICAgIGNtc1VJbnQ4TnVtYmVyIERpbWVuc2lvbnM4WzE2XTsKICAgIGNtc1VJbnQzMk51bWJlciBpLCBuTWF4R3JpZHMsIEdyaWRQb2ludHNbTUFYX0lOUFVUX0RJTUVOU0lPTlNdOwogICAgX2Ntc1N0YWdlQ0x1dERhdGEqIGNsdXQ7CgogICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJklucHV0Q2hhbnMpKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50MTZOdW1iZXIoaW8sICZPdXRwdXRDaGFucykpIHJldHVybiBOVUxMOwoKICAgIGlmIChJbnB1dENoYW5zID09IDApIGdvdG8gRXJyb3I7CiAgICBpZiAoT3V0cHV0Q2hhbnMgPT0gMCkgZ290byBFcnJvcjsKCiAgICBpZiAoaW8gLT5SZWFkKGlvLCBEaW1lbnNpb25zOCwgc2l6ZW9mKGNtc1VJbnQ4TnVtYmVyKSwgMTYpICE9IDE2KQogICAgICAgIGdvdG8gRXJyb3I7CgogICAgLy8gQ29weSBNQVhfSU5QVVRfRElNRU5TSU9OUyBhdCBtb3N0LiBFeHBhbmQgdG8gY21zVUludDMyTnVtYmVyCiAgICBuTWF4R3JpZHMgPSBJbnB1dENoYW5zID4gTUFYX0lOUFVUX0RJTUVOU0lPTlMgPyBNQVhfSU5QVVRfRElNRU5TSU9OUyA6IElucHV0Q2hhbnM7CiAgICBmb3IgKGk9MDsgaSA8IG5NYXhHcmlkczsgaSsrKSBHcmlkUG9pbnRzW2ldID0gKGNtc1VJbnQzMk51bWJlcikgRGltZW5zaW9uczhbaV07CgogICAgLy8gQWxsb2NhdGUgdGhlIHRydWUgQ0xVVAogICAgbXBlID0gY21zU3RhZ2VBbGxvY0NMdXRGbG9hdEdyYW51bGFyKHNlbGYgLT5Db250ZXh0SUQsIEdyaWRQb2ludHMsIElucHV0Q2hhbnMsIE91dHB1dENoYW5zLCBOVUxMKTsKICAgIGlmIChtcGUgPT0gTlVMTCkgZ290byBFcnJvcjsKCiAgICAvLyBSZWFkIHRoZSBkYXRhCiAgICBjbHV0ID0gKF9jbXNTdGFnZUNMdXREYXRhKikgbXBlIC0+RGF0YTsKICAgIGZvciAoaT0wOyBpIDwgY2x1dCAtPm5FbnRyaWVzOyBpKyspIHsKCiAgICAgICAgaWYgKCFfY21zUmVhZEZsb2F0MzJOdW1iZXIoaW8sICZjbHV0IC0+VGFiLlRGbG9hdFtpXSkpIGdvdG8gRXJyb3I7CiAgICB9CgogICAgKm5JdGVtcyA9IDE7CiAgICByZXR1cm4gbXBlOwoKRXJyb3I6CiAgICAqbkl0ZW1zID0gMDsKICAgIGlmIChtcGUgIT0gTlVMTCkgY21zU3RhZ2VGcmVlKG1wZSk7CiAgICByZXR1cm4gTlVMTDsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKFNpemVPZlRhZyk7Cn0KCi8vIFdyaXRlIGEgQ0xVVCBpbiBmbG9hdGluZyBwb2ludApzdGF0aWMKY21zQm9vbCAgVHlwZV9NUEVjbHV0X1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNVSW50OE51bWJlciBEaW1lbnNpb25zOFsxNl07CiAgICBjbXNVSW50MzJOdW1iZXIgaTsKICAgIGNtc1N0YWdlKiBtcGUgPSAoY21zU3RhZ2UqKSBQdHI7CiAgICBfY21zU3RhZ2VDTHV0RGF0YSogY2x1dCA9IChfY21zU3RhZ2VDTHV0RGF0YSopIG1wZSAtPkRhdGE7CgogICAgLy8gQ2hlY2sgZm9yIG1heGltdW0gbnVtYmVyIG9mIGNoYW5uZWxzCiAgICBpZiAobXBlIC0+IElucHV0Q2hhbm5lbHMgPiAxNSkgcmV0dXJuIEZBTFNFOwoKICAgIC8vIE9ubHkgZmxvYXRzIGFyZSBzdXBwb3J0ZWQgaW4gTVBFCiAgICBpZiAoY2x1dCAtPkhhc0Zsb2F0VmFsdWVzID09IEZBTFNFKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKCFfY21zV3JpdGVVSW50MTZOdW1iZXIoaW8sIChjbXNVSW50MTZOdW1iZXIpIG1wZSAtPklucHV0Q2hhbm5lbHMpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgKGNtc1VJbnQxNk51bWJlcikgbXBlIC0+T3V0cHV0Q2hhbm5lbHMpKSByZXR1cm4gRkFMU0U7CgogICAgbWVtc2V0KERpbWVuc2lvbnM4LCAwLCBzaXplb2YoRGltZW5zaW9uczgpKTsKCiAgICBmb3IgKGk9MDsgaSA8IG1wZSAtPklucHV0Q2hhbm5lbHM7IGkrKykKICAgICAgICBEaW1lbnNpb25zOFtpXSA9IChjbXNVSW50OE51bWJlcikgY2x1dCAtPlBhcmFtcyAtPm5TYW1wbGVzW2ldOwoKICAgIGlmICghaW8gLT5Xcml0ZShpbywgMTYsIERpbWVuc2lvbnM4KSkgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAoaT0wOyBpIDwgY2x1dCAtPm5FbnRyaWVzOyBpKyspIHsKCiAgICAgICAgaWYgKCFfY21zV3JpdGVGbG9hdDMyTnVtYmVyKGlvLCBjbHV0IC0+VGFiLlRGbG9hdFtpXSkpIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKG5JdGVtcyk7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKCi8vIFRoaXMgaXMgdGhlIGxpc3Qgb2YgYnVpbHQtaW4gTVBFIHR5cGVzCnN0YXRpYyBfY21zVGFnVHlwZUxpbmtlZExpc3QgU3VwcG9ydGVkTVBFdHlwZXNbXSA9IHsKCnt7IChjbXNUYWdUeXBlU2lnbmF0dXJlKSBjbXNTaWdCQWNzRWxlbVR5cGUsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIDAgfSwgJlN1cHBvcnRlZE1QRXR5cGVzWzFdIH0sICAgLy8gSWdub3JlIHRob3NlIGVsZW1lbnRzIGZvciBub3cKe3sgKGNtc1RhZ1R5cGVTaWduYXR1cmUpIGNtc1NpZ0VBY3NFbGVtVHlwZSwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCwgMCB9LCAmU3VwcG9ydGVkTVBFdHlwZXNbMl0gfSwgICAvLyAoVGhhdCdzIHdoYXQgdGhlIHNwZWMgc2F5cykKCntUWVBFX01QRV9IQU5ETEVSKChjbXNUYWdUeXBlU2lnbmF0dXJlKSBjbXNTaWdDdXJ2ZVNldEVsZW1UeXBlLCAgICAgTVBFY3VydmUpLCAgICAgICZTdXBwb3J0ZWRNUEV0eXBlc1szXSB9LAp7VFlQRV9NUEVfSEFORExFUigoY21zVGFnVHlwZVNpZ25hdHVyZSkgY21zU2lnTWF0cml4RWxlbVR5cGUsICAgICAgIE1QRW1hdHJpeCksICAgICAmU3VwcG9ydGVkTVBFdHlwZXNbNF0gfSwKe1RZUEVfTVBFX0hBTkRMRVIoKGNtc1RhZ1R5cGVTaWduYXR1cmUpIGNtc1NpZ0NMdXRFbGVtVHlwZSwgICAgICAgICBNUEVjbHV0KSwgICAgICAgIE5VTEwgfSwKfTsKCl9jbXNUYWdUeXBlUGx1Z2luQ2h1bmtUeXBlIF9jbXNNUEVUeXBlUGx1Z2luQ2h1bmsgPSB7IE5VTEwgfTsKCnN0YXRpYwpjbXNCb29sIFJlYWRNUEVFbGVtKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwKICAgICAgICAgICAgICAgICAgICBjbXNJT0hBTkRMRVIqIGlvLAogICAgICAgICAgICAgICAgICAgIHZvaWQqIENhcmdvLAogICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBuLAogICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc1N0YWdlU2lnbmF0dXJlIEVsZW1lbnRTaWc7CiAgICBjbXNUYWdUeXBlSGFuZGxlciogVHlwZUhhbmRsZXI7CiAgICBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zOwogICAgY21zUGlwZWxpbmUgKk5ld0xVVCA9IChjbXNQaXBlbGluZSAqKSBDYXJnbzsKICAgIF9jbXNUYWdUeXBlUGx1Z2luQ2h1bmtUeXBlKiBNUEVUeXBlUGx1Z2luQ2h1bmsgID0gKCBfY21zVGFnVHlwZVBsdWdpbkNodW5rVHlwZSopIF9jbXNDb250ZXh0R2V0Q2xpZW50Q2h1bmsoc2VsZi0+Q29udGV4dElELCBNUEVQbHVnaW4pOwoKCiAgICAvLyBUYWtlIHNpZ25hdHVyZSBhbmQgY2hhbm5lbHMgZm9yIGVhY2ggZWxlbWVudC4KICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sIChjbXNVSW50MzJOdW1iZXIqKSAmRWxlbWVudFNpZykpIHJldHVybiBGQUxTRTsKCiAgICAvLyBUaGUgcmVzZXJ2ZWQgcGxhY2Vob2xkZXIKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sIE5VTEwpKSByZXR1cm4gRkFMU0U7CgogICAgLy8gUmVhZCBkaXZlcnNlIE1QRSB0eXBlcwogICAgVHlwZUhhbmRsZXIgPSBHZXRIYW5kbGVyKChjbXNUYWdUeXBlU2lnbmF0dXJlKSBFbGVtZW50U2lnLCBNUEVUeXBlUGx1Z2luQ2h1bmsgLT5UYWdUeXBlcywgU3VwcG9ydGVkTVBFdHlwZXMpOwogICAgaWYgKFR5cGVIYW5kbGVyID09IE5VTEwpICB7CgogICAgICAgIGNoYXIgU3RyaW5nWzVdOwoKICAgICAgICBfY21zVGFnU2lnbmF0dXJlMlN0cmluZyhTdHJpbmcsIChjbXNUYWdTaWduYXR1cmUpIEVsZW1lbnRTaWcpOwoKICAgICAgICAvLyBBbiB1bmtub3duIGVsZW1lbnQgd2FzIGZvdW5kLgogICAgICAgIGNtc1NpZ25hbEVycm9yKHNlbGYgLT5Db250ZXh0SUQsIGNtc0VSUk9SX1VOS05PV05fRVhURU5TSU9OLCAiVW5rbm93biBNUEUgdHlwZSAnJXMnIGZvdW5kLiIsIFN0cmluZyk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8vIElmIG5vIHJlYWQgbWV0aG9kLCBqdXN0IGlnbm9yZSB0aGUgZWxlbWVudCAodmFsaWQgZm9yIGNtc1NpZ0JBY3NFbGVtVHlwZSBhbmQgY21zU2lnRUFjc0VsZW1UeXBlKQogICAgLy8gUmVhZCB0aGUgTVBFLiBObyBzaXplIGlzIGdpdmVuCiAgICBpZiAoVHlwZUhhbmRsZXIgLT5SZWFkUHRyICE9IE5VTEwpIHsKCiAgICAgICAgLy8gVGhpcyBpcyBhIHJlYWwgZWxlbWVudCB3aGljaCBzaG91bGQgYmUgcmVhZCBhbmQgcHJvY2Vzc2VkCiAgICAgICAgaWYgKCFjbXNQaXBlbGluZUluc2VydFN0YWdlKE5ld0xVVCwgY21zQVRfRU5ELCAoY21zU3RhZ2UqKSBUeXBlSGFuZGxlciAtPlJlYWRQdHIoc2VsZiwgaW8sICZuSXRlbXMsIFNpemVPZlRhZykpKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihTaXplT2ZUYWcpOwogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuKTsKfQoKCi8vIFRoaXMgaXMgdGhlIG1haW4gZGlzcGF0Y2hlciBmb3IgTVBFCnN0YXRpYwp2b2lkICpUeXBlX01QRV9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgIGNtc1VJbnQxNk51bWJlciBJbnB1dENoYW5zLCBPdXRwdXRDaGFuczsKICAgIGNtc1VJbnQzMk51bWJlciBFbGVtZW50Q291bnQ7CiAgICBjbXNQaXBlbGluZSAqTmV3TFVUID0gTlVMTDsKICAgIGNtc1VJbnQzMk51bWJlciBCYXNlT2Zmc2V0OwoKICAgIC8vIEdldCBhY3R1YWwgcG9zaXRpb24gYXMgYSBiYXNpcyBmb3IgZWxlbWVudCBvZmZzZXRzCiAgICBCYXNlT2Zmc2V0ID0gaW8gLT5UZWxsKGlvKSAtIHNpemVvZihfY21zVGFnQmFzZSk7CgogICAgLy8gUmVhZCBjaGFubmVscyBhbmQgZWxlbWVudCBjb3VudAogICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJklucHV0Q2hhbnMpKSByZXR1cm4gTlVMTDsKICAgIGlmICghX2Ntc1JlYWRVSW50MTZOdW1iZXIoaW8sICZPdXRwdXRDaGFucykpIHJldHVybiBOVUxMOwoKICAgIC8vIEFsbG9jYXRlcyBhbiBlbXB0eSBMVVQKICAgIE5ld0xVVCA9IGNtc1BpcGVsaW5lQWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgSW5wdXRDaGFucywgT3V0cHV0Q2hhbnMpOwogICAgaWYgKE5ld0xVVCA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmRWxlbWVudENvdW50KSkgcmV0dXJuIE5VTEw7CgogICAgaWYgKCFSZWFkUG9zaXRpb25UYWJsZShzZWxmLCBpbywgRWxlbWVudENvdW50LCBCYXNlT2Zmc2V0LCBOZXdMVVQsIFJlYWRNUEVFbGVtKSkgewogICAgICAgIGlmIChOZXdMVVQgIT0gTlVMTCkgY21zUGlwZWxpbmVGcmVlKE5ld0xVVCk7CiAgICAgICAgKm5JdGVtcyA9IDA7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLy8gU3VjY2VzcwogICAgKm5JdGVtcyA9IDE7CiAgICByZXR1cm4gTmV3TFVUOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIoU2l6ZU9mVGFnKTsKfQoKCgovLyBUaGlzIG9uZSBpcyBhIGxpaXRsZSBiaXQgbW9yZSBjb21wbGV4LCBzbyB3ZSBkb24ndCB1c2UgcG9zaXRpb24gdGFibGVzIHRoaXMgdGltZS4Kc3RhdGljCmNtc0Jvb2wgVHlwZV9NUEVfV3JpdGUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCB2b2lkKiBQdHIsIGNtc1VJbnQzMk51bWJlciBuSXRlbXMpCnsKICAgIGNtc1VJbnQzMk51bWJlciBpLCBCYXNlT2Zmc2V0LCBEaXJlY3RvcnlQb3MsIEN1cnJlbnRQb3M7CiAgICBpbnQgaW5wdXRDaGFuLCBvdXRwdXRDaGFuOwogICAgY21zVUludDMyTnVtYmVyIEVsZW1Db3VudDsKICAgIGNtc1VJbnQzMk51bWJlciAqRWxlbWVudE9mZnNldHMgPSBOVUxMLCAqRWxlbWVudFNpemVzID0gTlVMTCwgQmVmb3JlOwogICAgY21zU3RhZ2VTaWduYXR1cmUgRWxlbWVudFNpZzsKICAgIGNtc1BpcGVsaW5lKiBMdXQgPSAoY21zUGlwZWxpbmUqKSBQdHI7CiAgICBjbXNTdGFnZSogRWxlbSA9IEx1dCAtPkVsZW1lbnRzOwogICAgY21zVGFnVHlwZUhhbmRsZXIqIFR5cGVIYW5kbGVyOwogICAgX2Ntc1RhZ1R5cGVQbHVnaW5DaHVua1R5cGUqIE1QRVR5cGVQbHVnaW5DaHVuayAgPSAoIF9jbXNUYWdUeXBlUGx1Z2luQ2h1bmtUeXBlKikgX2Ntc0NvbnRleHRHZXRDbGllbnRDaHVuayhzZWxmLT5Db250ZXh0SUQsIE1QRVBsdWdpbik7CgogICAgQmFzZU9mZnNldCA9IGlvIC0+VGVsbChpbykgLSBzaXplb2YoX2Ntc1RhZ0Jhc2UpOwoKICAgIGlucHV0Q2hhbiAgPSBjbXNQaXBlbGluZUlucHV0Q2hhbm5lbHMoTHV0KTsKICAgIG91dHB1dENoYW4gPSBjbXNQaXBlbGluZU91dHB1dENoYW5uZWxzKEx1dCk7CiAgICBFbGVtQ291bnQgID0gY21zUGlwZWxpbmVTdGFnZUNvdW50KEx1dCk7CgogICAgRWxlbWVudE9mZnNldHMgPSAoY21zVUludDMyTnVtYmVyICopIF9jbXNDYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgRWxlbUNvdW50LCBzaXplb2YoY21zVUludDMyTnVtYmVyKSk7CiAgICBpZiAoRWxlbWVudE9mZnNldHMgPT0gTlVMTCkgZ290byBFcnJvcjsKCiAgICBFbGVtZW50U2l6ZXMgPSAoY21zVUludDMyTnVtYmVyICopIF9jbXNDYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgRWxlbUNvdW50LCBzaXplb2YoY21zVUludDMyTnVtYmVyKSk7CiAgICBpZiAoRWxlbWVudFNpemVzID09IE5VTEwpIGdvdG8gRXJyb3I7CgogICAgLy8gV3JpdGUgdGhlIGhlYWQKICAgIGlmICghX2Ntc1dyaXRlVUludDE2TnVtYmVyKGlvLCAoY21zVUludDE2TnVtYmVyKSBpbnB1dENoYW4pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zV3JpdGVVSW50MTZOdW1iZXIoaW8sIChjbXNVSW50MTZOdW1iZXIpIG91dHB1dENoYW4pKSBnb3RvIEVycm9yOwogICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIChjbXNVSW50MTZOdW1iZXIpIEVsZW1Db3VudCkpIGdvdG8gRXJyb3I7CgogICAgRGlyZWN0b3J5UG9zID0gaW8gLT5UZWxsKGlvKTsKCiAgICAvLyBXcml0ZSBhIGZha2UgZGlyZWN0b3J5IHRvIGJlIGZpbGxlZCBsYXR0ZXIgb24KICAgIGZvciAoaT0wOyBpIDwgRWxlbUNvdW50OyBpKyspIHsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgMCkpIGdvdG8gRXJyb3I7ICAvLyBPZmZzZXQKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgMCkpIGdvdG8gRXJyb3I7ICAvLyBzaXplCiAgICB9CgogICAgLy8gV3JpdGUgZWFjaCBzaW5nbGUgdGFnLiBLZWVwIHRyYWNrIG9mIHRoZSBzaXplIGFzIHdlbGwuCiAgICBmb3IgKGk9MDsgaSA8IEVsZW1Db3VudDsgaSsrKSB7CgogICAgICAgIEVsZW1lbnRPZmZzZXRzW2ldID0gaW8gLT5UZWxsKGlvKSAtIEJhc2VPZmZzZXQ7CgogICAgICAgIEVsZW1lbnRTaWcgPSBFbGVtIC0+VHlwZTsKCiAgICAgICAgVHlwZUhhbmRsZXIgPSBHZXRIYW5kbGVyKChjbXNUYWdUeXBlU2lnbmF0dXJlKSBFbGVtZW50U2lnLCBNUEVUeXBlUGx1Z2luQ2h1bmstPlRhZ1R5cGVzLCBTdXBwb3J0ZWRNUEV0eXBlcyk7CiAgICAgICAgaWYgKFR5cGVIYW5kbGVyID09IE5VTEwpICB7CgogICAgICAgICAgICAgICAgY2hhciBTdHJpbmdbNV07CgogICAgICAgICAgICAgICAgX2Ntc1RhZ1NpZ25hdHVyZTJTdHJpbmcoU3RyaW5nLCAoY21zVGFnU2lnbmF0dXJlKSBFbGVtZW50U2lnKTsKCiAgICAgICAgICAgICAgICAgLy8gQW4gdW5rbm93IGVsZW1lbnQgd2FzIGZvdW5kLgogICAgICAgICAgICAgICAgIGNtc1NpZ25hbEVycm9yKHNlbGYtPkNvbnRleHRJRCwgY21zRVJST1JfVU5LTk9XTl9FWFRFTlNJT04sICJGb3VuZCB1bmtub3duIE1QRSB0eXBlICclcyciLCBTdHJpbmcpOwogICAgICAgICAgICAgICAgIGdvdG8gRXJyb3I7CiAgICAgICAgfQoKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgRWxlbWVudFNpZykpIGdvdG8gRXJyb3I7CiAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIDApKSBnb3RvIEVycm9yOwogICAgICAgIEJlZm9yZSA9IGlvIC0+VGVsbChpbyk7CiAgICAgICAgaWYgKCFUeXBlSGFuZGxlciAtPldyaXRlUHRyKHNlbGYsIGlvLCBFbGVtLCAxKSkgZ290byBFcnJvcjsKICAgICAgICBpZiAoIV9jbXNXcml0ZUFsaWdubWVudChpbykpIGdvdG8gRXJyb3I7CgogICAgICAgIEVsZW1lbnRTaXplc1tpXSA9IGlvIC0+VGVsbChpbykgLSBCZWZvcmU7CgogICAgICAgIEVsZW0gPSBFbGVtIC0+TmV4dDsKICAgIH0KCiAgICAvLyBXcml0ZSB0aGUgZGlyZWN0b3J5CiAgICBDdXJyZW50UG9zID0gaW8gLT5UZWxsKGlvKTsKCiAgICBpZiAoIWlvIC0+U2VlayhpbywgRGlyZWN0b3J5UG9zKSkgZ290byBFcnJvcjsKCiAgICBmb3IgKGk9MDsgaSA8IEVsZW1Db3VudDsgaSsrKSB7CiAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MzJOdW1iZXIoaW8sIEVsZW1lbnRPZmZzZXRzW2ldKSkgZ290byBFcnJvcjsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgRWxlbWVudFNpemVzW2ldKSkgZ290byBFcnJvcjsKICAgIH0KCiAgICBpZiAoIWlvIC0+U2VlayhpbywgQ3VycmVudFBvcykpIGdvdG8gRXJyb3I7CgogICAgaWYgKEVsZW1lbnRPZmZzZXRzICE9IE5VTEwpIF9jbXNGcmVlKHNlbGYgLT5Db250ZXh0SUQsIEVsZW1lbnRPZmZzZXRzKTsKICAgIGlmIChFbGVtZW50U2l6ZXMgIT0gTlVMTCkgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgRWxlbWVudFNpemVzKTsKICAgIHJldHVybiBUUlVFOwoKRXJyb3I6CiAgICBpZiAoRWxlbWVudE9mZnNldHMgIT0gTlVMTCkgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgRWxlbWVudE9mZnNldHMpOwogICAgaWYgKEVsZW1lbnRTaXplcyAhPSBOVUxMKSBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBFbGVtZW50U2l6ZXMpOwogICAgcmV0dXJuIEZBTFNFOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKfQoKCnN0YXRpYwp2b2lkKiBUeXBlX01QRV9EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkICpQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICByZXR1cm4gKHZvaWQqKSBjbXNQaXBlbGluZUR1cCgoY21zUGlwZWxpbmUqKSBQdHIpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgpzdGF0aWMKdm9pZCBUeXBlX01QRV9GcmVlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgdm9pZCAqUHRyKQp7CiAgICBjbXNQaXBlbGluZUZyZWUoKGNtc1BpcGVsaW5lKikgUHRyKTsKICAgIHJldHVybjsKCiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBjbXNTaWdWY2d0VHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKCiNkZWZpbmUgY21zVmlkZW9DYXJkR2FtbWFUYWJsZVR5cGUgICAgMAojZGVmaW5lIGNtc1ZpZGVvQ2FyZEdhbW1hRm9ybXVsYVR5cGUgIDEKCi8vIFVzZWQgaW50ZXJuYWxseQp0eXBlZGVmIHN0cnVjdCB7CiAgICBkb3VibGUgR2FtbWE7CiAgICBkb3VibGUgTWluOwogICAgZG91YmxlIE1heDsKfSBfY21zVkNHVEdBTU1BOwoKCnN0YXRpYwp2b2lkICpUeXBlX3ZjZ3RfUmVhZChzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgIGNtc0lPSEFORExFUiogaW8sCiAgICAgICAgICAgICAgICAgICAgIGNtc1VJbnQzMk51bWJlciogbkl0ZW1zLAogICAgICAgICAgICAgICAgICAgICBjbXNVSW50MzJOdW1iZXIgU2l6ZU9mVGFnKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgVGFnVHlwZSwgbiwgaTsKICAgIGNtc1RvbmVDdXJ2ZSoqIEN1cnZlczsKCiAgICAqbkl0ZW1zID0gMDsKCiAgICAvLyBSZWFkIHRhZyB0eXBlCiAgICBpZiAoIV9jbXNSZWFkVUludDMyTnVtYmVyKGlvLCAmVGFnVHlwZSkpIHJldHVybiBOVUxMOwoKICAgIC8vIEFsbG9jYXRlIHNwYWNlIGZvciB0aGUgYXJyYXkKICAgIEN1cnZlcyA9ICggY21zVG9uZUN1cnZlKiopIF9jbXNDYWxsb2Moc2VsZiAtPkNvbnRleHRJRCwgMywgc2l6ZW9mKGNtc1RvbmVDdXJ2ZSopKTsKICAgIGlmIChDdXJ2ZXMgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgLy8gVGhlcmUgYXJlIHR3byBwb3NzaWJsZSBmbGF2b3JzCiAgICBzd2l0Y2ggKFRhZ1R5cGUpIHsKCiAgICAvLyBHYW1tYSBpcyBzdG9yZWQgYXMgYSB0YWJsZQogICAgY2FzZSBjbXNWaWRlb0NhcmRHYW1tYVRhYmxlVHlwZToKICAgIHsKICAgICAgIGNtc1VJbnQxNk51bWJlciBuQ2hhbm5lbHMsIG5FbGVtcywgbkJ5dGVzOwoKICAgICAgIC8vIENoZWNrIGNoYW5uZWwgY291bnQsIHdoaWNoIHNob3VsZCBiZSAzICh3ZSBkb24ndCBzdXBwb3J0IG1vbm9jaHJvbWUgdGhpcyB0aW1lKQogICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJm5DaGFubmVscykpIGdvdG8gRXJyb3I7CgogICAgICAgaWYgKG5DaGFubmVscyAhPSAzKSB7CiAgICAgICAgICAgY21zU2lnbmFsRXJyb3Ioc2VsZi0+Q29udGV4dElELCBjbXNFUlJPUl9VTktOT1dOX0VYVEVOU0lPTiwgIlVuc3VwcG9ydGVkIG51bWJlciBvZiBjaGFubmVscyBmb3IgVkNHVCAnJWQnIiwgbkNoYW5uZWxzKTsKICAgICAgICAgICBnb3RvIEVycm9yOwogICAgICAgfQoKICAgICAgIC8vIEdldCBUYWJsZSBlbGVtZW50IGNvdW50IGFuZCBieXRlcyBwZXIgZWxlbWVudAogICAgICAgaWYgKCFfY21zUmVhZFVJbnQxNk51bWJlcihpbywgJm5FbGVtcykpIGdvdG8gRXJyb3I7CiAgICAgICBpZiAoIV9jbXNSZWFkVUludDE2TnVtYmVyKGlvLCAmbkJ5dGVzKSkgZ290byBFcnJvcjsKCiAgICAgICAvLyBBZG9iZSdzIHF1aXJrIGZpeHVwLiBGaXhpbmcgYnJva2VuIHByb2ZpbGVzLi4uCiAgICAgICBpZiAobkVsZW1zID09IDI1NiAmJiBuQnl0ZXMgPT0gMSAmJiBTaXplT2ZUYWcgPT0gMTU3NikKICAgICAgICAgICBuQnl0ZXMgPSAyOwoKCiAgICAgICAvLyBQb3B1bGF0ZSB0b25lIGN1cnZlcwogICAgICAgZm9yIChuPTA7IG4gPCAzOyBuKyspIHsKCiAgICAgICAgICAgQ3VydmVzW25dID0gY21zQnVpbGRUYWJ1bGF0ZWRUb25lQ3VydmUxNihzZWxmIC0+Q29udGV4dElELCBuRWxlbXMsIE5VTEwpOwogICAgICAgICAgIGlmIChDdXJ2ZXNbbl0gPT0gTlVMTCkgZ290byBFcnJvcjsKCiAgICAgICAgICAgLy8gT24gZGVwZW5kaW5nIG9uIGJ5dGUgZGVwdGgKICAgICAgICAgICBzd2l0Y2ggKG5CeXRlcykgewoKICAgICAgICAgICAvLyBPbmUgYnl0ZSwgMC4uMjU1CiAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICBmb3IgKGk9MDsgaSA8IG5FbGVtczsgaSsrKSB7CgogICAgICAgICAgICAgICAgICAgY21zVUludDhOdW1iZXIgdjsKCiAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9jbXNSZWFkVUludDhOdW1iZXIoaW8sICZ2KSkgZ290byBFcnJvcjsKICAgICAgICAgICAgICAgICAgICAgIEN1cnZlc1tuXSAtPlRhYmxlMTZbaV0gPSBGUk9NXzhfVE9fMTYodik7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgIC8vIE9uZSB3b3JkIDAuLjY1NTM1CiAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgIGlmICghX2Ntc1JlYWRVSW50MTZBcnJheShpbywgbkVsZW1zLCBDdXJ2ZXNbbl0tPlRhYmxlMTYpKSBnb3RvIEVycm9yOwogICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIC8vIFVuc3VwcG9ydGVkCiAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICBjbXNTaWduYWxFcnJvcihzZWxmLT5Db250ZXh0SUQsIGNtc0VSUk9SX1VOS05PV05fRVhURU5TSU9OLCAiVW5zdXBwb3J0ZWQgYml0IGRlcHRoIGZvciBWQ0dUICclZCciLCBuQnl0ZXMgKiA4KTsKICAgICAgICAgICAgICBnb3RvIEVycm9yOwogICAgICAgICAgIH0KICAgICAgIH0gLy8gRm9yIGFsbCAzIGNoYW5uZWxzCiAgICB9CiAgICBicmVhazsKCiAgIC8vIEluIHRoaXMgY2FzZSwgZ2FtbWEgaXMgc3RvcmVkIGFzIGEgZm9ybXVsYQogICBjYXNlIGNtc1ZpZGVvQ2FyZEdhbW1hRm9ybXVsYVR5cGU6CiAgIHsKICAgICAgIF9jbXNWQ0dUR0FNTUEgQ29sb3JhbnRbM107CgogICAgICAgIC8vIFBvcHVsYXRlIHRvbmUgY3VydmVzCiAgICAgICBmb3IgKG49MDsgbiA8IDM7IG4rKykgewoKICAgICAgICAgICBkb3VibGUgUGFyYW1zWzEwXTsKCiAgICAgICAgICAgaWYgKCFfY21zUmVhZDE1Rml4ZWQxNk51bWJlcihpbywgJkNvbG9yYW50W25dLkdhbW1hKSkgZ290byBFcnJvcjsKICAgICAgICAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAmQ29sb3JhbnRbbl0uTWluKSkgZ290byBFcnJvcjsKICAgICAgICAgICBpZiAoIV9jbXNSZWFkMTVGaXhlZDE2TnVtYmVyKGlvLCAmQ29sb3JhbnRbbl0uTWF4KSkgZ290byBFcnJvcjsKCiAgICAgICAgICAgIC8vIFBhcmFtZXRyaWMgY3VydmUgdHlwZSA1IGlzOgogICAgICAgICAgICAvLyBZID0gKGFYICsgYileR2FtbWEgKyBlIHwgWCA+PSBkCiAgICAgICAgICAgIC8vIFkgPSBjWCArIGYgICAgICAgICAgICAgfCBYIDwgZAoKICAgICAgICAgICAgLy8gdmNndCBmb3JtdWxhIGlzOgogICAgICAgICAgICAvLyBZID0gKE1heCA/TWluKSAqIChYIF4gR2FtbWEpICsgTWluCgogICAgICAgICAgICAvLyBTbywgdGhlIHRyYW5zbGF0aW9uIGlzCiAgICAgICAgICAgIC8vIGEgPSAoTWF4ID9NaW4pIF4gKCAxIC8gR2FtbWEpCiAgICAgICAgICAgIC8vIGUgPSBNaW4KICAgICAgICAgICAgLy8gYj1jPWQ9Zj0wCgogICAgICAgICAgIFBhcmFtc1swXSA9IENvbG9yYW50W25dLkdhbW1hOwogICAgICAgICAgIFBhcmFtc1sxXSA9IHBvdygoQ29sb3JhbnRbbl0uTWF4IC0gQ29sb3JhbnRbbl0uTWluKSwgKDEuMCAvIENvbG9yYW50W25dLkdhbW1hKSk7CiAgICAgICAgICAgUGFyYW1zWzJdID0gMDsKICAgICAgICAgICBQYXJhbXNbM10gPSAwOwogICAgICAgICAgIFBhcmFtc1s0XSA9IDA7CiAgICAgICAgICAgUGFyYW1zWzVdID0gQ29sb3JhbnRbbl0uTWluOwogICAgICAgICAgIFBhcmFtc1s2XSA9IDA7CgogICAgICAgICAgIEN1cnZlc1tuXSA9IGNtc0J1aWxkUGFyYW1ldHJpY1RvbmVDdXJ2ZShzZWxmIC0+Q29udGV4dElELCA1LCBQYXJhbXMpOwogICAgICAgICAgIGlmIChDdXJ2ZXNbbl0gPT0gTlVMTCkgZ290byBFcnJvcjsKICAgICAgIH0KICAgfQogICBicmVhazsKCiAgIC8vIFVuc3VwcG9ydGVkCiAgIGRlZmF1bHQ6CiAgICAgIGNtc1NpZ25hbEVycm9yKHNlbGYtPkNvbnRleHRJRCwgY21zRVJST1JfVU5LTk9XTl9FWFRFTlNJT04sICJVbnN1cHBvcnRlZCB0YWcgdHlwZSBmb3IgVkNHVCAnJWQnIiwgVGFnVHlwZSk7CiAgICAgIGdvdG8gRXJyb3I7CiAgIH0KCiAgICpuSXRlbXMgPSAxOwogICByZXR1cm4gKHZvaWQqKSBDdXJ2ZXM7CgovLyBSZWdyZXQsICBmcmVlIGFsbCByZXNvdXJjZXMKRXJyb3I6CgogICAgY21zRnJlZVRvbmVDdXJ2ZVRyaXBsZShDdXJ2ZXMpOwogICAgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgQ3VydmVzKTsKICAgIHJldHVybiBOVUxMOwoKICAgICBjbXNVTlVTRURfUEFSQU1FVEVSKFNpemVPZlRhZyk7Cn0KCgovLyBXZSBkb24ndCBzdXBwb3J0IGFsbCBmbGF2b3JzLCBvbmx5IDE2Yml0cyB0YWJsZXMgYW5kIGZvcm11bGEKc3RhdGljCmNtc0Jvb2wgVHlwZV92Y2d0X1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNUb25lQ3VydmUqKiBDdXJ2ZXMgPSAgKGNtc1RvbmVDdXJ2ZSoqKSBQdHI7CiAgICBjbXNVSW50MzJOdW1iZXIgaSwgajsKCiAgICBpZiAoY21zR2V0VG9uZUN1cnZlUGFyYW1ldHJpY1R5cGUoQ3VydmVzWzBdKSA9PSA1ICYmCiAgICAgICAgY21zR2V0VG9uZUN1cnZlUGFyYW1ldHJpY1R5cGUoQ3VydmVzWzFdKSA9PSA1ICYmCiAgICAgICAgY21zR2V0VG9uZUN1cnZlUGFyYW1ldHJpY1R5cGUoQ3VydmVzWzJdKSA9PSA1KSB7CgogICAgICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgY21zVmlkZW9DYXJkR2FtbWFGb3JtdWxhVHlwZSkpIHJldHVybiBGQUxTRTsKCiAgICAgICAgICAgIC8vIFNhdmUgcGFyYW1ldGVycwogICAgICAgICAgICBmb3IgKGk9MDsgaSA8IDM7IGkrKykgewoKICAgICAgICAgICAgICAgIF9jbXNWQ0dUR0FNTUEgdjsKCiAgICAgICAgICAgICAgICB2LkdhbW1hID0gQ3VydmVzW2ldIC0+U2VnbWVudHNbMF0uUGFyYW1zWzBdOwogICAgICAgICAgICAgICAgdi5NaW4gICA9IEN1cnZlc1tpXSAtPlNlZ21lbnRzWzBdLlBhcmFtc1s1XTsKICAgICAgICAgICAgICAgIHYuTWF4ICAgPSBwb3coQ3VydmVzW2ldIC0+U2VnbWVudHNbMF0uUGFyYW1zWzFdLCB2LkdhbW1hKSArIHYuTWluOwoKICAgICAgICAgICAgICAgIGlmICghX2Ntc1dyaXRlMTVGaXhlZDE2TnVtYmVyKGlvLCB2LkdhbW1hKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIHYuTWluKSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAgICAgaWYgKCFfY21zV3JpdGUxNUZpeGVkMTZOdW1iZXIoaW8sIHYuTWF4KSkgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICB9CgogICAgZWxzZSB7CgogICAgICAgIC8vIEFsd2F5cyBzdG9yZSBhcyBhIHRhYmxlIG9mIDI1NiB3b3JkcwogICAgICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBjbXNWaWRlb0NhcmRHYW1tYVRhYmxlVHlwZSkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgMykpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIV9jbXNXcml0ZVVJbnQxNk51bWJlcihpbywgMjU2KSkgcmV0dXJuIEZBTFNFOwogICAgICAgIGlmICghX2Ntc1dyaXRlVUludDE2TnVtYmVyKGlvLCAyKSkgcmV0dXJuIEZBTFNFOwoKICAgICAgICBmb3IgKGk9MDsgaSA8IDM7IGkrKykgewogICAgICAgICAgICBmb3IgKGo9MDsgaiA8IDI1NjsgaisrKSB7CgogICAgICAgICAgICAgICAgY21zRmxvYXQzMk51bWJlciB2ID0gY21zRXZhbFRvbmVDdXJ2ZUZsb2F0KEN1cnZlc1tpXSwgKGNtc0Zsb2F0MzJOdW1iZXIpIChqIC8gMjU1LjApKTsKICAgICAgICAgICAgICAgIGNtc1VJbnQxNk51bWJlciAgbiA9IF9jbXNRdWlja1NhdHVyYXRlV29yZCh2ICogNjU1MzUuMCk7CgogICAgICAgICAgICAgICAgaWYgKCFfY21zV3JpdGVVSW50MTZOdW1iZXIoaW8sIG4pKSByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFRSVUU7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihzZWxmKTsKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobkl0ZW1zKTsKfQoKc3RhdGljCnZvaWQqIFR5cGVfdmNndF9EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkICpQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICBjbXNUb25lQ3VydmUqKiBPbGRDdXJ2ZXMgPSAgKGNtc1RvbmVDdXJ2ZSoqKSBQdHI7CiAgICBjbXNUb25lQ3VydmUqKiBOZXdDdXJ2ZXM7CgogICAgTmV3Q3VydmVzID0gKCBjbXNUb25lQ3VydmUqKikgX2Ntc0NhbGxvYyhzZWxmIC0+Q29udGV4dElELCAzLCBzaXplb2YoY21zVG9uZUN1cnZlKikpOwogICAgaWYgKE5ld0N1cnZlcyA9PSBOVUxMKSByZXR1cm4gTlVMTDsKCiAgICBOZXdDdXJ2ZXNbMF0gPSBjbXNEdXBUb25lQ3VydmUoT2xkQ3VydmVzWzBdKTsKICAgIE5ld0N1cnZlc1sxXSA9IGNtc0R1cFRvbmVDdXJ2ZShPbGRDdXJ2ZXNbMV0pOwogICAgTmV3Q3VydmVzWzJdID0gY21zRHVwVG9uZUN1cnZlKE9sZEN1cnZlc1syXSk7CgogICAgcmV0dXJuICh2b2lkKikgTmV3Q3VydmVzOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7Cn0KCgpzdGF0aWMKdm9pZCBUeXBlX3ZjZ3RfRnJlZShzdHJ1Y3QgX2Ntc190eXBlaGFuZGxlcl9zdHJ1Y3QqIHNlbGYsIHZvaWQqIFB0cikKewogICAgY21zRnJlZVRvbmVDdXJ2ZVRyaXBsZSgoY21zVG9uZUN1cnZlKiopIFB0cik7CiAgICBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBQdHIpOwp9CgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBjbXNTaWdEaWN0VHlwZQovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKLy8gU2luZ2xlIGNvbHVtbiBvZiB0aGUgdGFibGUgY2FuIHBvaW50IHRvIHdjaGFyIG9yIE1MVUMgZWxlbWVudHMuIEhvbGRzIGFycmF5cyBvZiBkYXRhCnR5cGVkZWYgc3RydWN0IHsKICAgIGNtc0NvbnRleHQgQ29udGV4dElEOwogICAgY21zVUludDMyTnVtYmVyICpPZmZzZXRzOwogICAgY21zVUludDMyTnVtYmVyICpTaXplczsKfSBfY21zRElDZWxlbTsKCnR5cGVkZWYgc3RydWN0IHsKICAgIF9jbXNESUNlbGVtIE5hbWUsIFZhbHVlLCBEaXNwbGF5TmFtZSwgRGlzcGxheVZhbHVlOwoKfSBfY21zRElDYXJyYXk7CgovLyBBbGxvY2F0ZSBhbiBlbXB0eSBhcnJheSBlbGVtZW50CnN0YXRpYwpjbXNCb29sIEFsbG9jRWxlbShjbXNDb250ZXh0IENvbnRleHRJRCwgX2Ntc0RJQ2VsZW0qIGUsICBjbXNVSW50MzJOdW1iZXIgQ291bnQpCnsKICAgIGUtPk9mZnNldHMgPSAoY21zVUludDMyTnVtYmVyICopIF9jbXNDYWxsb2MoQ29udGV4dElELCBDb3VudCwgc2l6ZW9mKGNtc1VJbnQzMk51bWJlcikpOwogICAgaWYgKGUtPk9mZnNldHMgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgIGUtPlNpemVzID0gKGNtc1VJbnQzMk51bWJlciAqKSBfY21zQ2FsbG9jKENvbnRleHRJRCwgQ291bnQsIHNpemVvZihjbXNVSW50MzJOdW1iZXIpKTsKICAgIGlmIChlLT5TaXplcyA9PSBOVUxMKSB7CgogICAgICAgIF9jbXNGcmVlKENvbnRleHRJRCwgZSAtPiBPZmZzZXRzKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgZSAtPkNvbnRleHRJRCA9IENvbnRleHRJRDsKICAgIHJldHVybiBUUlVFOwp9CgovLyBGcmVlIGFuIGFycmF5IGVsZW1lbnQKc3RhdGljCnZvaWQgRnJlZUVsZW0oX2Ntc0RJQ2VsZW0qIGUpCnsKICAgIGlmIChlIC0+T2Zmc2V0cyAhPSBOVUxMKSAgX2Ntc0ZyZWUoZSAtPiBDb250ZXh0SUQsIGUgLT4gT2Zmc2V0cyk7CiAgICBpZiAoZSAtPlNpemVzICAgIT0gTlVMTCkgIF9jbXNGcmVlKGUgLT4gQ29udGV4dElELCBlIC0+IFNpemVzKTsKICAgIGUtPk9mZnNldHMgPSBlIC0+U2l6ZXMgPSBOVUxMOwp9CgovLyBHZXQgcmlkIG9mIHdob2xlIGFycmF5CnN0YXRpYwp2b2lkIEZyZWVBcnJheSggX2Ntc0RJQ2FycmF5KiBhKQp7CiAgICBpZiAoYSAtPk5hbWUuT2Zmc2V0cyAhPSBOVUxMKSBGcmVlRWxlbSgmYS0+TmFtZSk7CiAgICBpZiAoYSAtPlZhbHVlLk9mZnNldHMgIT0gTlVMTCkgRnJlZUVsZW0oJmEgLT5WYWx1ZSk7CiAgICBpZiAoYSAtPkRpc3BsYXlOYW1lLk9mZnNldHMgIT0gTlVMTCkgRnJlZUVsZW0oJmEtPkRpc3BsYXlOYW1lKTsKICAgIGlmIChhIC0+RGlzcGxheVZhbHVlLk9mZnNldHMgIT0gTlVMTCkgRnJlZUVsZW0oJmEgLT5EaXNwbGF5VmFsdWUpOwp9CgoKLy8gQWxsb2NhdGUgd2hvbGUgYXJyYXkKc3RhdGljCmNtc0Jvb2wgQWxsb2NBcnJheShjbXNDb250ZXh0IENvbnRleHRJRCwgX2Ntc0RJQ2FycmF5KiBhLCBjbXNVSW50MzJOdW1iZXIgQ291bnQsIGNtc1VJbnQzMk51bWJlciBMZW5ndGgpCnsKICAgIC8vIEVtcHR5IHZhbHVlcwogICAgbWVtc2V0KGEsIDAsIHNpemVvZihfY21zRElDYXJyYXkpKTsKCiAgICAvLyBPbiBkZXBlbmRpbmcgb24gcmVjb3JkIHNpemUsIGNyZWF0ZSBjb2x1bW4gYXJyYXlzCiAgICBpZiAoIUFsbG9jRWxlbShDb250ZXh0SUQsICZhIC0+TmFtZSwgQ291bnQpKSBnb3RvIEVycm9yOwogICAgaWYgKCFBbGxvY0VsZW0oQ29udGV4dElELCAmYSAtPlZhbHVlLCBDb3VudCkpIGdvdG8gRXJyb3I7CgogICAgaWYgKExlbmd0aCA+IDE2KSB7CiAgICAgICAgaWYgKCFBbGxvY0VsZW0oQ29udGV4dElELCAmYSAtPiBEaXNwbGF5TmFtZSwgQ291bnQpKSBnb3RvIEVycm9yOwoKICAgIH0KICAgIGlmIChMZW5ndGggPiAyNCkgewogICAgICAgIGlmICghQWxsb2NFbGVtKENvbnRleHRJRCwgJmEgLT5EaXNwbGF5VmFsdWUsIENvdW50KSkgZ290byBFcnJvcjsKICAgIH0KICAgIHJldHVybiBUUlVFOwoKRXJyb3I6CiAgICBGcmVlQXJyYXkoYSk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8vIFJlYWQgb25lIGVsZW1lbnQKc3RhdGljCmNtc0Jvb2wgUmVhZE9uZUVsZW0oY21zSU9IQU5ETEVSKiBpbywgIF9jbXNESUNlbGVtKiBlLCBjbXNVSW50MzJOdW1iZXIgaSwgY21zVUludDMyTnVtYmVyIEJhc2VPZmZzZXQpCnsKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZlLT5PZmZzZXRzW2ldKSkgcmV0dXJuIEZBTFNFOwogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJmUgLT5TaXplc1tpXSkpIHJldHVybiBGQUxTRTsKCiAgICAvLyBBbiBvZmZzZXQgb2YgemVybyBoYXMgc3BlY2lhbCBtZWFuaW5nIGFuZCBzaGFsIGJlIHByZXNlcnZlZAogICAgaWYgKGUgLT5PZmZzZXRzW2ldID4gMCkKICAgICAgICBlIC0+T2Zmc2V0c1tpXSArPSBCYXNlT2Zmc2V0OwogICAgcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMKY21zQm9vbCBSZWFkT2Zmc2V0QXJyYXkoY21zSU9IQU5ETEVSKiBpbywgIF9jbXNESUNhcnJheSogYSwgY21zVUludDMyTnVtYmVyIENvdW50LCBjbXNVSW50MzJOdW1iZXIgTGVuZ3RoLCBjbXNVSW50MzJOdW1iZXIgQmFzZU9mZnNldCkKewogICAgY21zVUludDMyTnVtYmVyIGk7CgogICAgLy8gUmVhZCBjb2x1bW4gYXJyYXlzCiAgICBmb3IgKGk9MDsgaSA8IENvdW50OyBpKyspIHsKCiAgICAgICAgaWYgKCFSZWFkT25lRWxlbShpbywgJmEgLT4gTmFtZSwgaSwgQmFzZU9mZnNldCkpIHJldHVybiBGQUxTRTsKICAgICAgICBpZiAoIVJlYWRPbmVFbGVtKGlvLCAmYSAtPiBWYWx1ZSwgaSwgQmFzZU9mZnNldCkpIHJldHVybiBGQUxTRTsKCiAgICAgICAgaWYgKExlbmd0aCA+IDE2KSB7CgogICAgICAgICAgICBpZiAoIVJlYWRPbmVFbGVtKGlvLCAmYSAtPkRpc3BsYXlOYW1lLCBpLCBCYXNlT2Zmc2V0KSkgcmV0dXJuIEZBTFNFOwoKICAgICAgICB9CgogICAgICAgIGlmIChMZW5ndGggPiAyNCkgewoKICAgICAgICAgICAgaWYgKCFSZWFkT25lRWxlbShpbywgJiBhIC0+IERpc3BsYXlWYWx1ZSwgaSwgQmFzZU9mZnNldCkpIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKCi8vIFdyaXRlIG9uZSBlbGVtZW50CnN0YXRpYwpjbXNCb29sIFdyaXRlT25lRWxlbShjbXNJT0hBTkRMRVIqIGlvLCAgX2Ntc0RJQ2VsZW0qIGUsIGNtc1VJbnQzMk51bWJlciBpKQp7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgZS0+T2Zmc2V0c1tpXSkpIHJldHVybiBGQUxTRTsKICAgIGlmICghX2Ntc1dyaXRlVUludDMyTnVtYmVyKGlvLCBlIC0+U2l6ZXNbaV0pKSByZXR1cm4gRkFMU0U7CgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYwpjbXNCb29sIFdyaXRlT2Zmc2V0QXJyYXkoY21zSU9IQU5ETEVSKiBpbywgIF9jbXNESUNhcnJheSogYSwgY21zVUludDMyTnVtYmVyIENvdW50LCBjbXNVSW50MzJOdW1iZXIgTGVuZ3RoKQp7CiAgICBjbXNVSW50MzJOdW1iZXIgaTsKCiAgICBmb3IgKGk9MDsgaSA8IENvdW50OyBpKyspIHsKCiAgICAgICAgaWYgKCFXcml0ZU9uZUVsZW0oaW8sICZhIC0+IE5hbWUsIGkpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgaWYgKCFXcml0ZU9uZUVsZW0oaW8sICZhIC0+IFZhbHVlLCBpKSkgIHJldHVybiBGQUxTRTsKCiAgICAgICAgaWYgKExlbmd0aCA+IDE2KSB7CgogICAgICAgICAgICBpZiAoIVdyaXRlT25lRWxlbShpbywgJmEgLT4gRGlzcGxheU5hbWUsIGkpKSAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KCiAgICAgICAgaWYgKExlbmd0aCA+IDI0KSB7CgogICAgICAgICAgICBpZiAoIVdyaXRlT25lRWxlbShpbywgJmEgLT4gRGlzcGxheVZhbHVlLCBpKSkgIHJldHVybiBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYwpjbXNCb29sIFJlYWRPbmVXQ2hhcihjbXNJT0hBTkRMRVIqIGlvLCAgX2Ntc0RJQ2VsZW0qIGUsIGNtc1VJbnQzMk51bWJlciBpLCB3Y2hhcl90ICoqIHdjc3RyKQp7CgogICAgY21zVUludDMyTnVtYmVyIG5DaGFyczsKCiAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgdW5kZWZpbmVkIHN0cmluZ3MgKHNlZSBJQ0MgVm90YWJsZQogICAgICAvLyBQcm9wb3NhbCBTdWJtaXNzaW9uLCBEaWN0aW9uYXJ5IFR5cGUgYW5kIE1ldGFkYXRhIFRBRyBEZWZpbml0aW9uKQogICAgICBpZiAoZSAtPiBPZmZzZXRzW2ldID09IDApIHsKCiAgICAgICAgICAqd2NzdHIgPSBOVUxMOwogICAgICAgICAgcmV0dXJuIFRSVUU7CiAgICAgIH0KCiAgICAgIGlmICghaW8gLT4gU2VlayhpbywgZSAtPiBPZmZzZXRzW2ldKSkgcmV0dXJuIEZBTFNFOwoKICAgICAgbkNoYXJzID0gZSAtPlNpemVzW2ldIC8gc2l6ZW9mKGNtc1VJbnQxNk51bWJlcik7CgoKICAgICAgKndjc3RyID0gKHdjaGFyX3QqKSBfY21zTWFsbG9jWmVybyhlIC0+Q29udGV4dElELCAobkNoYXJzICsgMSkgKiBzaXplb2Yod2NoYXJfdCkpOwogICAgICBpZiAoKndjc3RyID09IE5VTEwpIHJldHVybiBGQUxTRTsKCiAgICAgIGlmICghX2Ntc1JlYWRXQ2hhckFycmF5KGlvLCBuQ2hhcnMsICp3Y3N0cikpIHsKICAgICAgICAgIF9jbXNGcmVlKGUgLT5Db250ZXh0SUQsICp3Y3N0cik7CiAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgIH0KCiAgICAgIC8vIEVuZCBvZiBzdHJpbmcgbWFya2VyCiAgICAgICgqd2NzdHIpW25DaGFyc10gPSAwOwogICAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljCmNtc1VJbnQzMk51bWJlciBteXdjc2xlbihjb25zdCB3Y2hhcl90ICpzKQp7CiAgICBjb25zdCB3Y2hhcl90ICpwOwoKICAgIHAgPSBzOwogICAgd2hpbGUgKCpwKQogICAgICAgIHArKzsKCiAgICByZXR1cm4gKGNtc1VJbnQzMk51bWJlcikocCAtIHMpOwp9CgpzdGF0aWMKY21zQm9vbCBXcml0ZU9uZVdDaGFyKGNtc0lPSEFORExFUiogaW8sICBfY21zRElDZWxlbSogZSwgY21zVUludDMyTnVtYmVyIGksIGNvbnN0IHdjaGFyX3QgKiB3Y3N0ciwgY21zVUludDMyTnVtYmVyIEJhc2VPZmZzZXQpCnsKICAgIGNtc1VJbnQzMk51bWJlciBCZWZvcmUgPSBpbyAtPlRlbGwoaW8pOwogICAgY21zVUludDMyTnVtYmVyIG47CgogICAgZSAtPk9mZnNldHNbaV0gPSBCZWZvcmUgLSBCYXNlT2Zmc2V0OwoKICAgIGlmICh3Y3N0ciA9PSBOVUxMKSB7CiAgICAgICAgZSAtPlNpemVzW2ldID0gMDsKICAgICAgICBlIC0+T2Zmc2V0c1tpXSA9IDA7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgbiA9IG15d2NzbGVuKHdjc3RyKTsKICAgIGlmICghX2Ntc1dyaXRlV0NoYXJBcnJheShpbywgIG4sIHdjc3RyKSkgcmV0dXJuIEZBTFNFOwoKICAgIGUgLT5TaXplc1tpXSA9IGlvIC0+VGVsbChpbykgLSBCZWZvcmU7CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljCmNtc0Jvb2wgUmVhZE9uZU1MVUMoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjbXNJT0hBTkRMRVIqIGlvLCAgX2Ntc0RJQ2VsZW0qIGUsIGNtc1VJbnQzMk51bWJlciBpLCBjbXNNTFUqKiBtbHUpCnsKICAgIGNtc1VJbnQzMk51bWJlciBuSXRlbXMgPSAwOwoKICAgIC8vIEEgd2F5IHRvIGdldCBudWxsIE1MVUNzCiAgICBpZiAoZSAtPiBPZmZzZXRzW2ldID09IDAgfHwgZSAtPlNpemVzW2ldID09IDApIHsKCiAgICAgICAgKm1sdSA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CgogICAgaWYgKCFpbyAtPiBTZWVrKGlvLCBlIC0+IE9mZnNldHNbaV0pKSByZXR1cm4gRkFMU0U7CgogICAgKm1sdSA9IChjbXNNTFUqKSBUeXBlX01MVV9SZWFkKHNlbGYsIGlvLCAmbkl0ZW1zLCBlIC0+U2l6ZXNbaV0pOwogICAgcmV0dXJuICptbHUgIT0gTlVMTDsKfQoKc3RhdGljCmNtc0Jvb2wgV3JpdGVPbmVNTFVDKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgIF9jbXNESUNlbGVtKiBlLCBjbXNVSW50MzJOdW1iZXIgaSwgY29uc3QgY21zTUxVKiBtbHUsIGNtc1VJbnQzMk51bWJlciBCYXNlT2Zmc2V0KQp7CiAgICBjbXNVSW50MzJOdW1iZXIgQmVmb3JlOwoKICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIHVuZGVmaW5lZCBzdHJpbmdzIChzZWUgSUNDIFZvdGFibGUKICAgICAvLyBQcm9wb3NhbCBTdWJtaXNzaW9uLCBEaWN0aW9uYXJ5IFR5cGUgYW5kIE1ldGFkYXRhIFRBRyBEZWZpbml0aW9uKQogICAgIGlmIChtbHUgPT0gTlVMTCkgewogICAgICAgIGUgLT5TaXplc1tpXSA9IDA7CiAgICAgICAgZSAtPk9mZnNldHNbaV0gPSAwOwogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIEJlZm9yZSA9IGlvIC0+VGVsbChpbyk7CiAgICBlIC0+T2Zmc2V0c1tpXSA9IEJlZm9yZSAtIEJhc2VPZmZzZXQ7CgogICAgaWYgKCFUeXBlX01MVV9Xcml0ZShzZWxmLCBpbywgKHZvaWQqKSBtbHUsIDEpKSByZXR1cm4gRkFMU0U7CgogICAgZSAtPlNpemVzW2ldID0gaW8gLT5UZWxsKGlvKSAtIEJlZm9yZTsKICAgIHJldHVybiBUUlVFOwp9CgoKc3RhdGljCnZvaWQgKlR5cGVfRGljdGlvbmFyeV9SZWFkKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgY21zVUludDMyTnVtYmVyKiBuSXRlbXMsIGNtc1VJbnQzMk51bWJlciBTaXplT2ZUYWcpCnsKICAgY21zSEFORExFIGhEaWN0OwogICBjbXNVSW50MzJOdW1iZXIgaSwgQ291bnQsIExlbmd0aDsKICAgY21zVUludDMyTnVtYmVyIEJhc2VPZmZzZXQ7CiAgIF9jbXNESUNhcnJheSBhOwogICB3Y2hhcl90ICpOYW1lV0NTID0gTlVMTCwgKlZhbHVlV0NTID0gTlVMTDsKICAgY21zTUxVICpEaXNwbGF5TmFtZU1MVSA9IE5VTEwsICpEaXNwbGF5VmFsdWVNTFU9TlVMTDsKICAgY21zQm9vbCByYzsKCiAgICAqbkl0ZW1zID0gMDsKCiAgICAvLyBHZXQgYWN0dWFsIHBvc2l0aW9uIGFzIGEgYmFzaXMgZm9yIGVsZW1lbnQgb2Zmc2V0cwogICAgQmFzZU9mZnNldCA9IGlvIC0+VGVsbChpbykgLSBzaXplb2YoX2Ntc1RhZ0Jhc2UpOwoKICAgIC8vIEdldCBuYW1lLXZhbHVlIHJlY29yZCBjb3VudAogICAgaWYgKCFfY21zUmVhZFVJbnQzMk51bWJlcihpbywgJkNvdW50KSkgcmV0dXJuIE5VTEw7CiAgICBTaXplT2ZUYWcgLT0gc2l6ZW9mKGNtc1VJbnQzMk51bWJlcik7CgogICAgLy8gR2V0IHJlYyBsZW5ndGgKICAgIGlmICghX2Ntc1JlYWRVSW50MzJOdW1iZXIoaW8sICZMZW5ndGgpKSByZXR1cm4gTlVMTDsKICAgIFNpemVPZlRhZyAtPSBzaXplb2YoY21zVUludDMyTnVtYmVyKTsKCiAgICAvLyBDaGVjayBmb3IgdmFsaWQgbGVuZ3RocwogICAgaWYgKExlbmd0aCAhPSAxNiAmJiBMZW5ndGggIT0gMjQgJiYgTGVuZ3RoICE9IDMyKSB7CiAgICAgICAgIGNtc1NpZ25hbEVycm9yKHNlbGYtPkNvbnRleHRJRCwgY21zRVJST1JfVU5LTk9XTl9FWFRFTlNJT04sICJVbmtub3duIHJlY29yZCBsZW5ndGggaW4gZGljdGlvbmFyeSAnJWQnIiwgTGVuZ3RoKTsKICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLy8gQ3JlYXRlcyBhbiBlbXB0eSBkaWN0aW9uYXJ5CiAgICBoRGljdCA9IGNtc0RpY3RBbGxvYyhzZWxmIC0+IENvbnRleHRJRCk7CiAgICBpZiAoaERpY3QgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CgogICAgLy8gT24gZGVwZW5kaW5nIG9uIHJlY29yZCBzaXplLCBjcmVhdGUgY29sdW1uIGFycmF5cwogICAgaWYgKCFBbGxvY0FycmF5KHNlbGYgLT4gQ29udGV4dElELCAmYSwgQ291bnQsIExlbmd0aCkpIGdvdG8gRXJyb3I7CgogICAgLy8gUmVhZCBjb2x1bW4gYXJyYXlzCiAgICBpZiAoIVJlYWRPZmZzZXRBcnJheShpbywgJmEsIENvdW50LCBMZW5ndGgsIEJhc2VPZmZzZXQpKSBnb3RvIEVycm9yOwoKICAgIC8vIFNlZWsgdG8gZWFjaCBlbGVtZW50IGFuZCByZWFkIGl0CiAgICBmb3IgKGk9MDsgaSA8IENvdW50OyBpKyspIHsKCiAgICAgICAgaWYgKCFSZWFkT25lV0NoYXIoaW8sICZhLk5hbWUsIGksICZOYW1lV0NTKSkgZ290byBFcnJvcjsKICAgICAgICBpZiAoIVJlYWRPbmVXQ2hhcihpbywgJmEuVmFsdWUsIGksICZWYWx1ZVdDUykpIGdvdG8gRXJyb3I7CgogICAgICAgIGlmIChMZW5ndGggPiAxNikgewogICAgICAgICAgICBpZiAoIVJlYWRPbmVNTFVDKHNlbGYsIGlvLCAmYS5EaXNwbGF5TmFtZSwgaSwgJkRpc3BsYXlOYW1lTUxVKSkgZ290byBFcnJvcjsKICAgICAgICB9CgogICAgICAgIGlmIChMZW5ndGggPiAyNCkgewogICAgICAgICAgICBpZiAoIVJlYWRPbmVNTFVDKHNlbGYsIGlvLCAmYS5EaXNwbGF5VmFsdWUsIGksICZEaXNwbGF5VmFsdWVNTFUpKSBnb3RvIEVycm9yOwogICAgICAgIH0KCiAgICAgICAgaWYgKE5hbWVXQ1MgPT0gTlVMTCB8fCBWYWx1ZVdDUyA9PSBOVUxMKSB7CiAgICAgICAgCiAgICAgICAgICAgIGNtc1NpZ25hbEVycm9yKHNlbGYtPkNvbnRleHRJRCwgY21zRVJST1JfQ09SUlVQVElPTl9ERVRFQ1RFRCwgIkJhZCBkaWN0aW9uYXJ5IE5hbWUvVmFsdWUiKTsgICAgICAgIAogICAgICAgICAgICByYyA9IEZBTFNFOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKCiAgICAgICAgICAgIHJjID0gY21zRGljdEFkZEVudHJ5KGhEaWN0LCBOYW1lV0NTLCBWYWx1ZVdDUywgRGlzcGxheU5hbWVNTFUsIERpc3BsYXlWYWx1ZU1MVSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoTmFtZVdDUyAhPSBOVUxMKSBfY21zRnJlZShzZWxmIC0+Q29udGV4dElELCBOYW1lV0NTKTsKICAgICAgICBpZiAoVmFsdWVXQ1MgIT0gTlVMTCkgX2Ntc0ZyZWUoc2VsZiAtPkNvbnRleHRJRCwgVmFsdWVXQ1MpOwogICAgICAgIGlmIChEaXNwbGF5TmFtZU1MVSAhPSBOVUxMKSBjbXNNTFVmcmVlKERpc3BsYXlOYW1lTUxVKTsKICAgICAgICBpZiAoRGlzcGxheVZhbHVlTUxVICE9IE5VTEwpIGNtc01MVWZyZWUoRGlzcGxheVZhbHVlTUxVKTsKCiAgICAgICAgaWYgKCFyYykgZ290byBFcnJvcjsKICAgIH0KCiAgIEZyZWVBcnJheSgmYSk7CiAgICpuSXRlbXMgPSAxOwogICByZXR1cm4gKHZvaWQqKSBoRGljdDsKCkVycm9yOgogICBGcmVlQXJyYXkoJmEpOwogICBjbXNEaWN0RnJlZShoRGljdCk7CiAgIHJldHVybiBOVUxMOwp9CgoKc3RhdGljCmNtc0Jvb2wgVHlwZV9EaWN0aW9uYXJ5X1dyaXRlKHN0cnVjdCBfY21zX3R5cGVoYW5kbGVyX3N0cnVjdCogc2VsZiwgY21zSU9IQU5ETEVSKiBpbywgdm9pZCogUHRyLCBjbXNVSW50MzJOdW1iZXIgbkl0ZW1zKQp7CiAgICBjbXNIQU5ETEUgaERpY3QgPSAoY21zSEFORExFKSBQdHI7CiAgICBjb25zdCBjbXNESUNUZW50cnkqIHA7CiAgICBjbXNCb29sIEFueU5hbWUsIEFueVZhbHVlOwogICAgY21zVUludDMyTnVtYmVyIGksIENvdW50LCBMZW5ndGg7CiAgICBjbXNVSW50MzJOdW1iZXIgRGlyZWN0b3J5UG9zLCBDdXJyZW50UG9zLCBCYXNlT2Zmc2V0OwogICBfY21zRElDYXJyYXkgYTsKCiAgICBpZiAoaERpY3QgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgIEJhc2VPZmZzZXQgPSBpbyAtPlRlbGwoaW8pIC0gc2l6ZW9mKF9jbXNUYWdCYXNlKTsKCiAgICAvLyBMZXQncyBpbnNwZWN0IHRoZSBkaWN0aW9uYXJ5CiAgICBDb3VudCA9IDA7IEFueU5hbWUgPSBGQUxTRTsgQW55VmFsdWUgPSBGQUxTRTsKICAgIGZvciAocCA9IGNtc0RpY3RHZXRFbnRyeUxpc3QoaERpY3QpOyBwICE9IE5VTEw7IHAgPSBjbXNEaWN0TmV4dEVudHJ5KHApKSB7CgogICAgICAgIGlmIChwIC0+RGlzcGxheU5hbWUgIT0gTlVMTCkgQW55TmFtZSA9IFRSVUU7CiAgICAgICAgaWYgKHAgLT5EaXNwbGF5VmFsdWUgIT0gTlVMTCkgQW55VmFsdWUgPSBUUlVFOwogICAgICAgIENvdW50Kys7CiAgICB9CgogICAgTGVuZ3RoID0gMTY7CiAgICBpZiAoQW55TmFtZSkgIExlbmd0aCArPSA4OwogICAgaWYgKEFueVZhbHVlKSBMZW5ndGggKz0gODsKCiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgQ291bnQpKSByZXR1cm4gRkFMU0U7CiAgICBpZiAoIV9jbXNXcml0ZVVJbnQzMk51bWJlcihpbywgTGVuZ3RoKSkgcmV0dXJuIEZBTFNFOwoKICAgIC8vIEtlZXAgc3RhcnRpbmcgcG9zaXRpb24gb2Ygb2Zmc2V0cyB0YWJsZQogICAgRGlyZWN0b3J5UG9zID0gaW8gLT5UZWxsKGlvKTsKCiAgICAvLyBBbGxvY2F0ZSBvZmZzZXRzIGFycmF5CiAgICBpZiAoIUFsbG9jQXJyYXkoc2VsZiAtPkNvbnRleHRJRCwgJmEsIENvdW50LCBMZW5ndGgpKSBnb3RvIEVycm9yOwoKICAgIC8vIFdyaXRlIGEgZmFrZSBkaXJlY3RvcnkgdG8gYmUgZmlsbGVkIGxhdHRlciBvbgogICAgaWYgKCFXcml0ZU9mZnNldEFycmF5KGlvLCAmYSwgQ291bnQsIExlbmd0aCkpIGdvdG8gRXJyb3I7CgogICAgLy8gV3JpdGUgZWFjaCBlbGVtZW50LiBLZWVwIHRyYWNrIG9mIHRoZSBzaXplIGFzIHdlbGwuCiAgICBwID0gY21zRGljdEdldEVudHJ5TGlzdChoRGljdCk7CiAgICBmb3IgKGk9MDsgaSA8IENvdW50OyBpKyspIHsKCiAgICAgICAgaWYgKCFXcml0ZU9uZVdDaGFyKGlvLCAmYS5OYW1lLCBpLCAgcCAtPk5hbWUsIEJhc2VPZmZzZXQpKSBnb3RvIEVycm9yOwogICAgICAgIGlmICghV3JpdGVPbmVXQ2hhcihpbywgJmEuVmFsdWUsIGksIHAgLT5WYWx1ZSwgQmFzZU9mZnNldCkpIGdvdG8gRXJyb3I7CgogICAgICAgIGlmIChwIC0+RGlzcGxheU5hbWUgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAoIVdyaXRlT25lTUxVQyhzZWxmLCBpbywgJmEuRGlzcGxheU5hbWUsIGksIHAgLT5EaXNwbGF5TmFtZSwgQmFzZU9mZnNldCkpIGdvdG8gRXJyb3I7CiAgICAgICAgfQoKICAgICAgICBpZiAocCAtPkRpc3BsYXlWYWx1ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIGlmICghV3JpdGVPbmVNTFVDKHNlbGYsIGlvLCAmYS5EaXNwbGF5VmFsdWUsIGksIHAgLT5EaXNwbGF5VmFsdWUsIEJhc2VPZmZzZXQpKSBnb3RvIEVycm9yOwogICAgICAgIH0KCiAgICAgICBwID0gY21zRGljdE5leHRFbnRyeShwKTsKICAgIH0KCiAgICAvLyBXcml0ZSB0aGUgZGlyZWN0b3J5CiAgICBDdXJyZW50UG9zID0gaW8gLT5UZWxsKGlvKTsKICAgIGlmICghaW8gLT5TZWVrKGlvLCBEaXJlY3RvcnlQb3MpKSBnb3RvIEVycm9yOwoKICAgIGlmICghV3JpdGVPZmZzZXRBcnJheShpbywgJmEsIENvdW50LCBMZW5ndGgpKSBnb3RvIEVycm9yOwoKICAgIGlmICghaW8gLT5TZWVrKGlvLCBDdXJyZW50UG9zKSkgZ290byBFcnJvcjsKCiAgICBGcmVlQXJyYXkoJmEpOwogICAgcmV0dXJuIFRSVUU7CgpFcnJvcjoKICAgIEZyZWVBcnJheSgmYSk7CiAgICByZXR1cm4gRkFMU0U7CgogICAgY21zVU5VU0VEX1BBUkFNRVRFUihuSXRlbXMpOwp9CgoKc3RhdGljCnZvaWQqIFR5cGVfRGljdGlvbmFyeV9EdXAoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCBjb25zdCB2b2lkICpQdHIsIGNtc1VJbnQzMk51bWJlciBuKQp7CiAgICByZXR1cm4gKHZvaWQqKSAgY21zRGljdER1cCgoY21zSEFORExFKSBQdHIpOwoKICAgIGNtc1VOVVNFRF9QQVJBTUVURVIobik7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKc3RhdGljCnZvaWQgVHlwZV9EaWN0aW9uYXJ5X0ZyZWUoc3RydWN0IF9jbXNfdHlwZWhhbmRsZXJfc3RydWN0KiBzZWxmLCB2b2lkKiBQdHIpCnsKICAgIGNtc0RpY3RGcmVlKChjbXNIQU5ETEUpIFB0cik7CiAgICBjbXNVTlVTRURfUEFSQU1FVEVSKHNlbGYpOwp9CgoKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gVHlwZSBzdXBwb3J0IG1haW4gcm91dGluZXMKLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCgovLyBUaGlzIGlzIHRoZSBsaXN0IG9mIGJ1aWx0LWluIHR5cGVzCnN0YXRpYyBfY21zVGFnVHlwZUxpbmtlZExpc3QgU3VwcG9ydGVkVGFnVHlwZXNbXSA9IHsKCntUWVBFX0hBTkRMRVIoY21zU2lnQ2hyb21hdGljaXR5VHlwZSwgICAgICAgICAgQ2hyb21hdGljaXR5KSwgICAgICAgICZTdXBwb3J0ZWRUYWdUeXBlc1sxXSB9LAp7VFlQRV9IQU5ETEVSKGNtc1NpZ0NvbG9yYW50T3JkZXJUeXBlLCAgICAgICAgIENvbG9yYW50T3JkZXJUeXBlKSwgICAmU3VwcG9ydGVkVGFnVHlwZXNbMl0gfSwKe1RZUEVfSEFORExFUihjbXNTaWdTMTVGaXhlZDE2QXJyYXlUeXBlLCAgICAgICBTMTVGaXhlZDE2KSwgICAgICAgICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzNdIH0sCntUWVBFX0hBTkRMRVIoY21zU2lnVTE2Rml4ZWQxNkFycmF5VHlwZSwgICAgICAgVTE2Rml4ZWQxNiksICAgICAgICAgICZTdXBwb3J0ZWRUYWdUeXBlc1s0XSB9LAp7VFlQRV9IQU5ETEVSKGNtc1NpZ1RleHRUeXBlLCAgICAgICAgICAgICAgICAgIFRleHQpLCAgICAgICAgICAgICAgICAmU3VwcG9ydGVkVGFnVHlwZXNbNV0gfSwKe1RZUEVfSEFORExFUihjbXNTaWdUZXh0RGVzY3JpcHRpb25UeXBlLCAgICAgICBUZXh0X0Rlc2NyaXB0aW9uKSwgICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzZdIH0sCntUWVBFX0hBTkRMRVIoY21zU2lnQ3VydmVUeXBlLCAgICAgICAgICAgICAgICAgQ3VydmUpLCAgICAgICAgICAgICAgICZTdXBwb3J0ZWRUYWdUeXBlc1s3XSB9LAp7VFlQRV9IQU5ETEVSKGNtc1NpZ1BhcmFtZXRyaWNDdXJ2ZVR5cGUsICAgICAgIFBhcmFtZXRyaWNDdXJ2ZSksICAgICAmU3VwcG9ydGVkVGFnVHlwZXNbOF0gfSwKe1RZUEVfSEFORExFUihjbXNTaWdEYXRlVGltZVR5cGUsICAgICAgICAgICAgICBEYXRlVGltZSksICAgICAgICAgICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzldIH0sCntUWVBFX0hBTkRMRVIoY21zU2lnTHV0OFR5cGUsICAgICAgICAgICAgICAgICAgTFVUOCksICAgICAgICAgICAgICAgICZTdXBwb3J0ZWRUYWdUeXBlc1sxMF0gfSwKe1RZUEVfSEFORExFUihjbXNTaWdMdXQxNlR5cGUsICAgICAgICAgICAgICAgICBMVVQxNiksICAgICAgICAgICAgICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzExXSB9LAp7VFlQRV9IQU5ETEVSKGNtc1NpZ0NvbG9yYW50VGFibGVUeXBlLCAgICAgICAgIENvbG9yYW50VGFibGUpLCAgICAgICAmU3VwcG9ydGVkVGFnVHlwZXNbMTJdIH0sCntUWVBFX0hBTkRMRVIoY21zU2lnTmFtZWRDb2xvcjJUeXBlLCAgICAgICAgICAgTmFtZWRDb2xvciksICAgICAgICAgICZTdXBwb3J0ZWRUYWdUeXBlc1sxM10gfSwKe1RZUEVfSEFORExFUihjbXNTaWdNdWx0aUxvY2FsaXplZFVuaWNvZGVUeXBlLCBNTFUpLCAgICAgICAgICAgICAgICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzE0XSB9LAp7VFlQRV9IQU5ETEVSKGNtc1NpZ1Byb2ZpbGVTZXF1ZW5jZURlc2NUeXBlLCAgIFByb2ZpbGVTZXF1ZW5jZURlc2MpLCAmU3VwcG9ydGVkVGFnVHlwZXNbMTVdIH0sCntUWVBFX0hBTkRMRVIoY21zU2lnU2lnbmF0dXJlVHlwZSwgICAgICAgICAgICAgU2lnbmF0dXJlKSwgICAgICAgICAgICZTdXBwb3J0ZWRUYWdUeXBlc1sxNl0gfSwKe1RZUEVfSEFORExFUihjbXNTaWdNZWFzdXJlbWVudFR5cGUsICAgICAgICAgICBNZWFzdXJlbWVudCksICAgICAgICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzE3XSB9LAp7VFlQRV9IQU5ETEVSKGNtc1NpZ0RhdGFUeXBlLCAgICAgICAgICAgICAgICAgIERhdGEpLCAgICAgICAgICAgICAgICAmU3VwcG9ydGVkVGFnVHlwZXNbMThdIH0sCntUWVBFX0hBTkRMRVIoY21zU2lnTHV0QXRvQlR5cGUsICAgICAgICAgICAgICAgTFVUQTJCKSwgICAgICAgICAgICAgICZTdXBwb3J0ZWRUYWdUeXBlc1sxOV0gfSwKe1RZUEVfSEFORExFUihjbXNTaWdMdXRCdG9BVHlwZSwgICAgICAgICAgICAgICBMVVRCMkEpLCAgICAgICAgICAgICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzIwXSB9LAp7VFlQRV9IQU5ETEVSKGNtc1NpZ1VjckJnVHlwZSwgICAgICAgICAgICAgICAgIFVjckJnKSwgICAgICAgICAgICAgICAmU3VwcG9ydGVkVGFnVHlwZXNbMjFdIH0sCntUWVBFX0hBTkRMRVIoY21zU2lnQ3JkSW5mb1R5cGUsICAgICAgICAgICAgICAgQ3JkSW5mbyksICAgICAgICAgICAgICZTdXBwb3J0ZWRUYWdUeXBlc1syMl0gfSwKe1RZUEVfSEFORExFUihjbXNTaWdNdWx0aVByb2Nlc3NFbGVtZW50VHlwZSwgICBNUEUpLCAgICAgICAgICAgICAgICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzIzXSB9LAp7VFlQRV9IQU5ETEVSKGNtc1NpZ1NjcmVlbmluZ1R5cGUsICAgICAgICAgICAgIFNjcmVlbmluZyksICAgICAgICAgICAmU3VwcG9ydGVkVGFnVHlwZXNbMjRdIH0sCntUWVBFX0hBTkRMRVIoY21zU2lnVmlld2luZ0NvbmRpdGlvbnNUeXBlLCAgICAgVmlld2luZ0NvbmRpdGlvbnMpLCAgICZTdXBwb3J0ZWRUYWdUeXBlc1syNV0gfSwKe1RZUEVfSEFORExFUihjbXNTaWdYWVpUeXBlLCAgICAgICAgICAgICAgICAgICBYWVopLCAgICAgICAgICAgICAgICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzI2XSB9LAp7VFlQRV9IQU5ETEVSKGNtc0NvcmJpc0Jyb2tlblhZWnR5cGUsICAgICAgICAgIFhZWiksICAgICAgICAgICAgICAgICAmU3VwcG9ydGVkVGFnVHlwZXNbMjddIH0sCntUWVBFX0hBTkRMRVIoY21zTW9uYWNvQnJva2VuQ3VydmVUeXBlLCAgICAgICAgQ3VydmUpLCAgICAgICAgICAgICAgICZTdXBwb3J0ZWRUYWdUeXBlc1syOF0gfSwKe1RZUEVfSEFORExFUihjbXNTaWdQcm9maWxlU2VxdWVuY2VJZFR5cGUsICAgICBQcm9maWxlU2VxdWVuY2VJZCksICAgJlN1cHBvcnRlZFRhZ1R5cGVzWzI5XSB9LAp7VFlQRV9IQU5ETEVSKGNtc1NpZ0RpY3RUeXBlLCAgICAgICAgICAgICAgICAgIERpY3Rpb25hcnkpLCAgICAgICAgICAmU3VwcG9ydGVkVGFnVHlwZXNbMzBdIH0sCntUWVBFX0hBTkRMRVIoY21zU2lnVmNndFR5cGUsICAgICAgICAgICAgICAgICAgdmNndCksICAgICAgICAgICAgICAgIE5VTEwgfQp9OwoKCl9jbXNUYWdUeXBlUGx1Z2luQ2h1bmtUeXBlIF9jbXNUYWdUeXBlUGx1Z2luQ2h1bmsgPSB7IE5VTEwgfTsKCgoKLy8gRHVwbGljYXRlcyB0aGUgem9uZSBvZiBtZW1vcnkgdXNlZCBieSB0aGUgcGx1Zy1pbiBpbiB0aGUgbmV3IGNvbnRleHQKc3RhdGljCnZvaWQgRHVwVGFnVHlwZUxpc3Qoc3RydWN0IF9jbXNDb250ZXh0X3N0cnVjdCogY3R4LCAKICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJ1Y3QgX2Ntc0NvbnRleHRfc3RydWN0KiBzcmMsIAogICAgICAgICAgICAgICAgICAgIGludCBsb2MpCnsKICAgX2Ntc1RhZ1R5cGVQbHVnaW5DaHVua1R5cGUgbmV3SGVhZCA9IHsgTlVMTCB9OwogICBfY21zVGFnVHlwZUxpbmtlZExpc3QqICBlbnRyeTsKICAgX2Ntc1RhZ1R5cGVMaW5rZWRMaXN0KiAgQW50ZXJpb3IgPSBOVUxMOwogICBfY21zVGFnVHlwZVBsdWdpbkNodW5rVHlwZSogaGVhZCA9IChfY21zVGFnVHlwZVBsdWdpbkNodW5rVHlwZSopIHNyYy0+Y2h1bmtzW2xvY107CgogICAvLyBXYWxrIHRoZSBsaXN0IGNvcHlpbmcgYWxsIG5vZGVzCiAgIGZvciAoZW50cnkgPSBoZWFkLT5UYWdUeXBlczsKICAgICAgIGVudHJ5ICE9IE5VTEw7CiAgICAgICBlbnRyeSA9IGVudHJ5IC0+TmV4dCkgewoKICAgICAgICAgICBfY21zVGFnVHlwZUxpbmtlZExpc3QgKm5ld0VudHJ5ID0gKCBfY21zVGFnVHlwZUxpbmtlZExpc3QgKikgX2Ntc1N1YkFsbG9jRHVwKGN0eCAtPk1lbVBvb2wsIGVudHJ5LCBzaXplb2YoX2Ntc1RhZ1R5cGVMaW5rZWRMaXN0KSk7CgogICAgICAgICAgIGlmIChuZXdFbnRyeSA9PSBOVUxMKSAKICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAvLyBXZSB3YW50IHRvIGtlZXAgdGhlIGxpbmtlZCBsaXN0IG9yZGVyLCBzbyB0aGlzIGlzIGEgbGl0dGxlIGJpdCB0cmlja3kKICAgICAgICAgICBuZXdFbnRyeSAtPiBOZXh0ID0gTlVMTDsKICAgICAgICAgICBpZiAoQW50ZXJpb3IpCiAgICAgICAgICAgICAgIEFudGVyaW9yIC0+IE5leHQgPSBuZXdFbnRyeTsKCiAgICAgICAgICAgQW50ZXJpb3IgPSBuZXdFbnRyeTsKCiAgICAgICAgICAgaWYgKG5ld0hlYWQuVGFnVHlwZXMgPT0gTlVMTCkKICAgICAgICAgICAgICAgbmV3SGVhZC5UYWdUeXBlcyA9IG5ld0VudHJ5OwogICB9CgogICBjdHggLT5jaHVua3NbbG9jXSA9IF9jbXNTdWJBbGxvY0R1cChjdHgtPk1lbVBvb2wsICZuZXdIZWFkLCBzaXplb2YoX2Ntc1RhZ1R5cGVQbHVnaW5DaHVua1R5cGUpKTsKfQoKCnZvaWQgX2Ntc0FsbG9jVGFnVHlwZVBsdWdpbkNodW5rKHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIGN0eCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIHNyYykKewogICAgaWYgKHNyYyAhPSBOVUxMKSB7CiAgICAgICAgCiAgICAgICAgLy8gRHVwbGljYXRlIHRoZSBMSVNUCiAgICAgICAgRHVwVGFnVHlwZUxpc3QoY3R4LCBzcmMsIFRhZ1R5cGVQbHVnaW4pOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgc3RhdGljIF9jbXNUYWdUeXBlUGx1Z2luQ2h1bmtUeXBlIFRhZ1R5cGVQbHVnaW5DaHVuayA9IHsgTlVMTCB9OwogICAgICAgIGN0eCAtPmNodW5rc1tUYWdUeXBlUGx1Z2luXSA9IF9jbXNTdWJBbGxvY0R1cChjdHggLT5NZW1Qb29sLCAmVGFnVHlwZVBsdWdpbkNodW5rLCBzaXplb2YoX2Ntc1RhZ1R5cGVQbHVnaW5DaHVua1R5cGUpKTsKICAgIH0KfQoKdm9pZCBfY21zQWxsb2NNUEVUeXBlUGx1Z2luQ2h1bmsoc3RydWN0IF9jbXNDb250ZXh0X3N0cnVjdCogY3R4LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIHNyYykKewogICAgaWYgKHNyYyAhPSBOVUxMKSB7CiAgICAgICAgCiAgICAgICAgLy8gRHVwbGljYXRlIHRoZSBMSVNUCiAgICAgICAgRHVwVGFnVHlwZUxpc3QoY3R4LCBzcmMsIE1QRVBsdWdpbik7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBzdGF0aWMgX2Ntc1RhZ1R5cGVQbHVnaW5DaHVua1R5cGUgVGFnVHlwZVBsdWdpbkNodW5rID0geyBOVUxMIH07CiAgICAgICAgY3R4IC0+Y2h1bmtzW01QRVBsdWdpbl0gPSBfY21zU3ViQWxsb2NEdXAoY3R4IC0+TWVtUG9vbCwgJlRhZ1R5cGVQbHVnaW5DaHVuaywgc2l6ZW9mKF9jbXNUYWdUeXBlUGx1Z2luQ2h1bmtUeXBlKSk7CiAgICB9Cgp9CgoKLy8gQm90aCBraW5kIG9mIHBsdWctaW5zIHNoYXJlIHNhbWUgc3RydWN0dXJlCmNtc0Jvb2wgIF9jbXNSZWdpc3RlclRhZ1R5cGVQbHVnaW4oY21zQ29udGV4dCBpZCwgY21zUGx1Z2luQmFzZSogRGF0YSkKewogICAgcmV0dXJuIFJlZ2lzdGVyVHlwZXNQbHVnaW4oaWQsIERhdGEsIFRhZ1R5cGVQbHVnaW4pOwp9CgpjbXNCb29sICBfY21zUmVnaXN0ZXJNdWx0aVByb2Nlc3NFbGVtZW50UGx1Z2luKGNtc0NvbnRleHQgaWQsIGNtc1BsdWdpbkJhc2UqIERhdGEpCnsKICAgIHJldHVybiBSZWdpc3RlclR5cGVzUGx1Z2luKGlkLCBEYXRhLE1QRVBsdWdpbik7Cn0KCgovLyBXcmFwcGVyIGZvciB0YWcgdHlwZXMKY21zVGFnVHlwZUhhbmRsZXIqIF9jbXNHZXRUYWdUeXBlSGFuZGxlcihjbXNDb250ZXh0IENvbnRleHRJRCwgY21zVGFnVHlwZVNpZ25hdHVyZSBzaWcpCnsKICAgIF9jbXNUYWdUeXBlUGx1Z2luQ2h1bmtUeXBlKiBjdHggPSAoIF9jbXNUYWdUeXBlUGx1Z2luQ2h1bmtUeXBlKikgX2Ntc0NvbnRleHRHZXRDbGllbnRDaHVuayhDb250ZXh0SUQsIFRhZ1R5cGVQbHVnaW4pOwoKICAgIHJldHVybiBHZXRIYW5kbGVyKHNpZywgY3R4LT5UYWdUeXBlcywgU3VwcG9ydGVkVGFnVHlwZXMpOwp9CgovLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBUYWcgc3VwcG9ydCBtYWluIHJvdXRpbmVzCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgp0eXBlZGVmIHN0cnVjdCBfY21zVGFnTGlua2VkTGlzdF9zdCB7CgogICAgICAgICAgICBjbXNUYWdTaWduYXR1cmUgU2lnbmF0dXJlOwogICAgICAgICAgICBjbXNUYWdEZXNjcmlwdG9yIERlc2NyaXB0b3I7CiAgICAgICAgICAgIHN0cnVjdCBfY21zVGFnTGlua2VkTGlzdF9zdCogTmV4dDsKCn0gX2Ntc1RhZ0xpbmtlZExpc3Q7CgovLyBUaGlzIGlzIHRoZSBsaXN0IG9mIGJ1aWx0LWluIHRhZ3MKc3RhdGljIF9jbXNUYWdMaW5rZWRMaXN0IFN1cHBvcnRlZFRhZ3NbXSA9IHsKCiAgICB7IGNtc1NpZ0FUb0IwVGFnLCAgICAgICAgICAgICAgIHsgMSwgMywgIHsgY21zU2lnTHV0MTZUeXBlLCAgY21zU2lnTHV0QXRvQlR5cGUsIGNtc1NpZ0x1dDhUeXBlfSwgRGVjaWRlTFVUdHlwZUEyQn0sICZTdXBwb3J0ZWRUYWdzWzFdfSwKICAgIHsgY21zU2lnQVRvQjFUYWcsICAgICAgICAgICAgICAgeyAxLCAzLCAgeyBjbXNTaWdMdXQxNlR5cGUsICBjbXNTaWdMdXRBdG9CVHlwZSwgY21zU2lnTHV0OFR5cGV9LCBEZWNpZGVMVVR0eXBlQTJCfSwgJlN1cHBvcnRlZFRhZ3NbMl19LAogICAgeyBjbXNTaWdBVG9CMlRhZywgICAgICAgICAgICAgICB7IDEsIDMsICB7IGNtc1NpZ0x1dDE2VHlwZSwgIGNtc1NpZ0x1dEF0b0JUeXBlLCBjbXNTaWdMdXQ4VHlwZX0sIERlY2lkZUxVVHR5cGVBMkJ9LCAmU3VwcG9ydGVkVGFnc1szXX0sCiAgICB7IGNtc1NpZ0JUb0EwVGFnLCAgICAgICAgICAgICAgIHsgMSwgMywgIHsgY21zU2lnTHV0MTZUeXBlLCAgY21zU2lnTHV0QnRvQVR5cGUsIGNtc1NpZ0x1dDhUeXBlfSwgRGVjaWRlTFVUdHlwZUIyQX0sICZTdXBwb3J0ZWRUYWdzWzRdfSwKICAgIHsgY21zU2lnQlRvQTFUYWcsICAgICAgICAgICAgICAgeyAxLCAzLCAgeyBjbXNTaWdMdXQxNlR5cGUsICBjbXNTaWdMdXRCdG9BVHlwZSwgY21zU2lnTHV0OFR5cGV9LCBEZWNpZGVMVVR0eXBlQjJBfSwgJlN1cHBvcnRlZFRhZ3NbNV19LAogICAgeyBjbXNTaWdCVG9BMlRhZywgICAgICAgICAgICAgICB7IDEsIDMsICB7IGNtc1NpZ0x1dDE2VHlwZSwgIGNtc1NpZ0x1dEJ0b0FUeXBlLCBjbXNTaWdMdXQ4VHlwZX0sIERlY2lkZUxVVHR5cGVCMkF9LCAmU3VwcG9ydGVkVGFnc1s2XX0sCgogICAgLy8gQWxsb3cgY29yYmlzICBhbmQgaXRzIGJyb2tlbiBYWVogdHlwZQogICAgeyBjbXNTaWdSZWRDb2xvcmFudFRhZywgICAgICAgICB7IDEsIDIsIHsgY21zU2lnWFlaVHlwZSwgY21zQ29yYmlzQnJva2VuWFladHlwZSB9LCBEZWNpZGVYWVp0eXBlfSwgJlN1cHBvcnRlZFRhZ3NbN119LAogICAgeyBjbXNTaWdHcmVlbkNvbG9yYW50VGFnLCAgICAgICB7IDEsIDIsIHsgY21zU2lnWFlaVHlwZSwgY21zQ29yYmlzQnJva2VuWFladHlwZSB9LCBEZWNpZGVYWVp0eXBlfSwgJlN1cHBvcnRlZFRhZ3NbOF19LAogICAgeyBjbXNTaWdCbHVlQ29sb3JhbnRUYWcsICAgICAgICB7IDEsIDIsIHsgY21zU2lnWFlaVHlwZSwgY21zQ29yYmlzQnJva2VuWFladHlwZSB9LCBEZWNpZGVYWVp0eXBlfSwgJlN1cHBvcnRlZFRhZ3NbOV19LAoKICAgIHsgY21zU2lnUmVkVFJDVGFnLCAgICAgICAgICAgICAgeyAxLCAzLCB7IGNtc1NpZ0N1cnZlVHlwZSwgY21zU2lnUGFyYW1ldHJpY0N1cnZlVHlwZSwgY21zTW9uYWNvQnJva2VuQ3VydmVUeXBlIH0sIERlY2lkZUN1cnZlVHlwZX0sICZTdXBwb3J0ZWRUYWdzWzEwXX0sCiAgICB7IGNtc1NpZ0dyZWVuVFJDVGFnLCAgICAgICAgICAgIHsgMSwgMywgeyBjbXNTaWdDdXJ2ZVR5cGUsIGNtc1NpZ1BhcmFtZXRyaWNDdXJ2ZVR5cGUsIGNtc01vbmFjb0Jyb2tlbkN1cnZlVHlwZSB9LCBEZWNpZGVDdXJ2ZVR5cGV9LCAmU3VwcG9ydGVkVGFnc1sxMV19LAogICAgeyBjbXNTaWdCbHVlVFJDVGFnLCAgICAgICAgICAgICB7IDEsIDMsIHsgY21zU2lnQ3VydmVUeXBlLCBjbXNTaWdQYXJhbWV0cmljQ3VydmVUeXBlLCBjbXNNb25hY29Ccm9rZW5DdXJ2ZVR5cGUgfSwgRGVjaWRlQ3VydmVUeXBlfSwgJlN1cHBvcnRlZFRhZ3NbMTJdfSwKCiAgICB7IGNtc1NpZ0NhbGlicmF0aW9uRGF0ZVRpbWVUYWcsIHsgMSwgMSwgeyBjbXNTaWdEYXRlVGltZVR5cGUgfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzEzXX0sCiAgICB7IGNtc1NpZ0NoYXJUYXJnZXRUYWcsICAgICAgICAgIHsgMSwgMSwgeyBjbXNTaWdUZXh0VHlwZSB9LCAgICAgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzE0XX0sCgogICAgeyBjbXNTaWdDaHJvbWF0aWNBZGFwdGF0aW9uVGFnLCB7IDksIDEsIHsgY21zU2lnUzE1Rml4ZWQxNkFycmF5VHlwZSB9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbMTVdfSwKICAgIHsgY21zU2lnQ2hyb21hdGljaXR5VGFnLCAgICAgICAgeyAxLCAxLCB7IGNtc1NpZ0Nocm9tYXRpY2l0eVR5cGUgICAgfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzE2XX0sCiAgICB7IGNtc1NpZ0NvbG9yYW50T3JkZXJUYWcsICAgICAgIHsgMSwgMSwgeyBjbXNTaWdDb2xvcmFudE9yZGVyVHlwZSAgIH0sIE5VTEx9LCAmU3VwcG9ydGVkVGFnc1sxN119LAogICAgeyBjbXNTaWdDb2xvcmFudFRhYmxlVGFnLCAgICAgICB7IDEsIDEsIHsgY21zU2lnQ29sb3JhbnRUYWJsZVR5cGUgICB9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbMThdfSwKICAgIHsgY21zU2lnQ29sb3JhbnRUYWJsZU91dFRhZywgICAgeyAxLCAxLCB7IGNtc1NpZ0NvbG9yYW50VGFibGVUeXBlICAgfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzE5XX0sCgogICAgeyBjbXNTaWdDb3B5cmlnaHRUYWcsICAgICAgICAgICB7IDEsIDMsIHsgY21zU2lnVGV4dFR5cGUsICBjbXNTaWdNdWx0aUxvY2FsaXplZFVuaWNvZGVUeXBlLCBjbXNTaWdUZXh0RGVzY3JpcHRpb25UeXBlfSwgRGVjaWRlVGV4dFR5cGV9LCAmU3VwcG9ydGVkVGFnc1syMF19LAogICAgeyBjbXNTaWdEYXRlVGltZVRhZywgICAgICAgICAgICB7IDEsIDEsIHsgY21zU2lnRGF0ZVRpbWVUeXBlIH0sIE5VTEx9LCAmU3VwcG9ydGVkVGFnc1syMV19LAoKICAgIHsgY21zU2lnRGV2aWNlTWZnRGVzY1RhZywgICAgICAgeyAxLCAzLCB7IGNtc1NpZ1RleHREZXNjcmlwdGlvblR5cGUsIGNtc1NpZ011bHRpTG9jYWxpemVkVW5pY29kZVR5cGUsIGNtc1NpZ1RleHRUeXBlfSwgRGVjaWRlVGV4dERlc2NUeXBlfSwgJlN1cHBvcnRlZFRhZ3NbMjJdfSwKICAgIHsgY21zU2lnRGV2aWNlTW9kZWxEZXNjVGFnLCAgICAgeyAxLCAzLCB7IGNtc1NpZ1RleHREZXNjcmlwdGlvblR5cGUsIGNtc1NpZ011bHRpTG9jYWxpemVkVW5pY29kZVR5cGUsIGNtc1NpZ1RleHRUeXBlfSwgRGVjaWRlVGV4dERlc2NUeXBlfSwgJlN1cHBvcnRlZFRhZ3NbMjNdfSwKCiAgICB7IGNtc1NpZ0dhbXV0VGFnLCAgICAgICAgICAgICAgIHsgMSwgMywgeyBjbXNTaWdMdXQxNlR5cGUsIGNtc1NpZ0x1dEJ0b0FUeXBlLCBjbXNTaWdMdXQ4VHlwZSB9LCBEZWNpZGVMVVR0eXBlQjJBfSwgJlN1cHBvcnRlZFRhZ3NbMjRdfSwKCiAgICB7IGNtc1NpZ0dyYXlUUkNUYWcsICAgICAgICAgICAgIHsgMSwgMiwgeyBjbXNTaWdDdXJ2ZVR5cGUsIGNtc1NpZ1BhcmFtZXRyaWNDdXJ2ZVR5cGUgfSwgRGVjaWRlQ3VydmVUeXBlfSwgJlN1cHBvcnRlZFRhZ3NbMjVdfSwKICAgIHsgY21zU2lnTHVtaW5hbmNlVGFnLCAgICAgICAgICAgeyAxLCAxLCB7IGNtc1NpZ1hZWlR5cGUgfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzI2XX0sCgogICAgeyBjbXNTaWdNZWRpYUJsYWNrUG9pbnRUYWcsICAgICB7IDEsIDIsIHsgY21zU2lnWFlaVHlwZSwgY21zQ29yYmlzQnJva2VuWFladHlwZSB9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbMjddfSwKICAgIHsgY21zU2lnTWVkaWFXaGl0ZVBvaW50VGFnLCAgICAgeyAxLCAyLCB7IGNtc1NpZ1hZWlR5cGUsIGNtc0NvcmJpc0Jyb2tlblhZWnR5cGUgfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzI4XX0sCgogICAgeyBjbXNTaWdOYW1lZENvbG9yMlRhZywgICAgICAgICB7IDEsIDEsIHsgY21zU2lnTmFtZWRDb2xvcjJUeXBlIH0sIE5VTEx9LCAmU3VwcG9ydGVkVGFnc1syOV19LAoKICAgIHsgY21zU2lnUHJldmlldzBUYWcsICAgICAgICAgICAgeyAxLCAzLCAgeyBjbXNTaWdMdXQxNlR5cGUsIGNtc1NpZ0x1dEJ0b0FUeXBlLCBjbXNTaWdMdXQ4VHlwZSB9LCBEZWNpZGVMVVR0eXBlQjJBfSwgJlN1cHBvcnRlZFRhZ3NbMzBdfSwKICAgIHsgY21zU2lnUHJldmlldzFUYWcsICAgICAgICAgICAgeyAxLCAzLCAgeyBjbXNTaWdMdXQxNlR5cGUsIGNtc1NpZ0x1dEJ0b0FUeXBlLCBjbXNTaWdMdXQ4VHlwZSB9LCBEZWNpZGVMVVR0eXBlQjJBfSwgJlN1cHBvcnRlZFRhZ3NbMzFdfSwKICAgIHsgY21zU2lnUHJldmlldzJUYWcsICAgICAgICAgICAgeyAxLCAzLCAgeyBjbXNTaWdMdXQxNlR5cGUsIGNtc1NpZ0x1dEJ0b0FUeXBlLCBjbXNTaWdMdXQ4VHlwZSB9LCBEZWNpZGVMVVR0eXBlQjJBfSwgJlN1cHBvcnRlZFRhZ3NbMzJdfSwKCiAgICB7IGNtc1NpZ1Byb2ZpbGVEZXNjcmlwdGlvblRhZywgIHsgMSwgMywgeyBjbXNTaWdUZXh0RGVzY3JpcHRpb25UeXBlLCBjbXNTaWdNdWx0aUxvY2FsaXplZFVuaWNvZGVUeXBlLCBjbXNTaWdUZXh0VHlwZX0sIERlY2lkZVRleHREZXNjVHlwZX0sICZTdXBwb3J0ZWRUYWdzWzMzXX0sCiAgICB7IGNtc1NpZ1Byb2ZpbGVTZXF1ZW5jZURlc2NUYWcsIHsgMSwgMSwgeyBjbXNTaWdQcm9maWxlU2VxdWVuY2VEZXNjVHlwZSB9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbMzRdfSwKICAgIHsgY21zU2lnVGVjaG5vbG9neVRhZywgICAgICAgICAgeyAxLCAxLCB7IGNtc1NpZ1NpZ25hdHVyZVR5cGUgfSwgTlVMTH0sICAmU3VwcG9ydGVkVGFnc1szNV19LAoKICAgIHsgY21zU2lnQ29sb3JpbWV0cmljSW50ZW50SW1hZ2VTdGF0ZVRhZywgICB7IDEsIDEsIHsgY21zU2lnU2lnbmF0dXJlVHlwZSB9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbMzZdfSwKICAgIHsgY21zU2lnUGVyY2VwdHVhbFJlbmRlcmluZ0ludGVudEdhbXV0VGFnLCB7IDEsIDEsIHsgY21zU2lnU2lnbmF0dXJlVHlwZSB9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbMzddfSwKICAgIHsgY21zU2lnU2F0dXJhdGlvblJlbmRlcmluZ0ludGVudEdhbXV0VGFnLCB7IDEsIDEsIHsgY21zU2lnU2lnbmF0dXJlVHlwZSB9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbMzhdfSwKCiAgICB7IGNtc1NpZ01lYXN1cmVtZW50VGFnLCAgICAgICAgIHsgMSwgMSwgeyBjbXNTaWdNZWFzdXJlbWVudFR5cGUgfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzM5XX0sCgogICAgeyBjbXNTaWdQczJDUkQwVGFnLCAgICAgICAgICAgICB7IDEsIDEsIHsgY21zU2lnRGF0YVR5cGUgfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzQwXX0sCiAgICB7IGNtc1NpZ1BzMkNSRDFUYWcsICAgICAgICAgICAgIHsgMSwgMSwgeyBjbXNTaWdEYXRhVHlwZSB9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbNDFdfSwKICAgIHsgY21zU2lnUHMyQ1JEMlRhZywgICAgICAgICAgICAgeyAxLCAxLCB7IGNtc1NpZ0RhdGFUeXBlIH0sIE5VTEx9LCAmU3VwcG9ydGVkVGFnc1s0Ml19LAogICAgeyBjbXNTaWdQczJDUkQzVGFnLCAgICAgICAgICAgICB7IDEsIDEsIHsgY21zU2lnRGF0YVR5cGUgfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzQzXX0sCiAgICB7IGNtc1NpZ1BzMkNTQVRhZywgICAgICAgICAgICAgIHsgMSwgMSwgeyBjbXNTaWdEYXRhVHlwZSB9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbNDRdfSwKICAgIHsgY21zU2lnUHMyUmVuZGVyaW5nSW50ZW50VGFnLCAgeyAxLCAxLCB7IGNtc1NpZ0RhdGFUeXBlIH0sIE5VTEx9LCAmU3VwcG9ydGVkVGFnc1s0NV19LAoKICAgIHsgY21zU2lnVmlld2luZ0NvbmREZXNjVGFnLCAgICAgeyAxLCAzLCB7IGNtc1NpZ1RleHREZXNjcmlwdGlvblR5cGUsIGNtc1NpZ011bHRpTG9jYWxpemVkVW5pY29kZVR5cGUsIGNtc1NpZ1RleHRUeXBlfSwgRGVjaWRlVGV4dERlc2NUeXBlfSwgJlN1cHBvcnRlZFRhZ3NbNDZdfSwKCiAgICB7IGNtc1NpZ1VjckJnVGFnLCAgICAgICAgICAgICAgIHsgMSwgMSwgeyBjbXNTaWdVY3JCZ1R5cGV9LCBOVUxMfSwgICAgJlN1cHBvcnRlZFRhZ3NbNDddfSwKICAgIHsgY21zU2lnQ3JkSW5mb1RhZywgICAgICAgICAgICAgeyAxLCAxLCB7IGNtc1NpZ0NyZEluZm9UeXBlfSwgTlVMTH0sICAmU3VwcG9ydGVkVGFnc1s0OF19LAoKICAgIHsgY21zU2lnRFRvQjBUYWcsICAgICAgICAgICAgICAgeyAxLCAxLCB7IGNtc1NpZ011bHRpUHJvY2Vzc0VsZW1lbnRUeXBlfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzQ5XX0sCiAgICB7IGNtc1NpZ0RUb0IxVGFnLCAgICAgICAgICAgICAgIHsgMSwgMSwgeyBjbXNTaWdNdWx0aVByb2Nlc3NFbGVtZW50VHlwZX0sIE5VTEx9LCAmU3VwcG9ydGVkVGFnc1s1MF19LAogICAgeyBjbXNTaWdEVG9CMlRhZywgICAgICAgICAgICAgICB7IDEsIDEsIHsgY21zU2lnTXVsdGlQcm9jZXNzRWxlbWVudFR5cGV9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbNTFdfSwKICAgIHsgY21zU2lnRFRvQjNUYWcsICAgICAgICAgICAgICAgeyAxLCAxLCB7IGNtc1NpZ011bHRpUHJvY2Vzc0VsZW1lbnRUeXBlfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzUyXX0sCiAgICB7IGNtc1NpZ0JUb0QwVGFnLCAgICAgICAgICAgICAgIHsgMSwgMSwgeyBjbXNTaWdNdWx0aVByb2Nlc3NFbGVtZW50VHlwZX0sIE5VTEx9LCAmU3VwcG9ydGVkVGFnc1s1M119LAogICAgeyBjbXNTaWdCVG9EMVRhZywgICAgICAgICAgICAgICB7IDEsIDEsIHsgY21zU2lnTXVsdGlQcm9jZXNzRWxlbWVudFR5cGV9LCBOVUxMfSwgJlN1cHBvcnRlZFRhZ3NbNTRdfSwKICAgIHsgY21zU2lnQlRvRDJUYWcsICAgICAgICAgICAgICAgeyAxLCAxLCB7IGNtc1NpZ011bHRpUHJvY2Vzc0VsZW1lbnRUeXBlfSwgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzU1XX0sCiAgICB7IGNtc1NpZ0JUb0QzVGFnLCAgICAgICAgICAgICAgIHsgMSwgMSwgeyBjbXNTaWdNdWx0aVByb2Nlc3NFbGVtZW50VHlwZX0sIE5VTEx9LCAmU3VwcG9ydGVkVGFnc1s1Nl19LAoKICAgIHsgY21zU2lnU2NyZWVuaW5nRGVzY1RhZywgICAgICAgeyAxLCAxLCB7IGNtc1NpZ1RleHREZXNjcmlwdGlvblR5cGUgfSwgICAgTlVMTH0sICZTdXBwb3J0ZWRUYWdzWzU3XX0sCiAgICB7IGNtc1NpZ1ZpZXdpbmdDb25kaXRpb25zVGFnLCAgIHsgMSwgMSwgeyBjbXNTaWdWaWV3aW5nQ29uZGl0aW9uc1R5cGUgfSwgIE5VTEx9LCAmU3VwcG9ydGVkVGFnc1s1OF19LAoKICAgIHsgY21zU2lnU2NyZWVuaW5nVGFnLCAgICAgICAgICAgeyAxLCAxLCB7IGNtc1NpZ1NjcmVlbmluZ1R5cGV9LCAgICAgICAgICBOVUxMIH0sICZTdXBwb3J0ZWRUYWdzWzU5XX0sCiAgICB7IGNtc1NpZ1ZjZ3RUYWcsICAgICAgICAgICAgICAgIHsgMSwgMSwgeyBjbXNTaWdWY2d0VHlwZX0sICAgICAgICAgICAgICAgTlVMTCB9LCAmU3VwcG9ydGVkVGFnc1s2MF19LAogICAgeyBjbXNTaWdNZXRhVGFnLCAgICAgICAgICAgICAgICB7IDEsIDEsIHsgY21zU2lnRGljdFR5cGV9LCAgICAgICAgICAgICAgIE5VTEwgfSwgJlN1cHBvcnRlZFRhZ3NbNjFdfSwKICAgIHsgY21zU2lnUHJvZmlsZVNlcXVlbmNlSWRUYWcsICAgeyAxLCAxLCB7IGNtc1NpZ1Byb2ZpbGVTZXF1ZW5jZUlkVHlwZX0sICBOVUxMIH0sICAmU3VwcG9ydGVkVGFnc1s2Ml19LAogICAgeyBjbXNTaWdQcm9maWxlRGVzY3JpcHRpb25NTFRhZyx7IDEsIDEsIHsgY21zU2lnTXVsdGlMb2NhbGl6ZWRVbmljb2RlVHlwZX0sIE5VTEx9LCBOVUxMfQoKCn07CgovKgogICAgTm90IHN1cHBvcnRlZCAgICAgICAgICAgICAgICAgV2h5CiAgICA9PT09PT09PT09PT09PT09PT09PT09PSAgICAgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgY21zU2lnT3V0cHV0UmVzcG9uc2VUYWcgICA9PT4gV0FSTklORywgUE9TU0lCTEUgUEFURU5UIE9OIFRISVMgU1VCSkVDVCEKICAgIGNtc1NpZ05hbWVkQ29sb3JUYWcgICAgICAgPT0+IERlcHJlY2F0ZWQKICAgIGNtc1NpZ0RhdGFUYWcgICAgICAgICAgICAgPT0+IEFuY2llbnQsIHVudXNlZAogICAgY21zU2lnRGV2aWNlU2V0dGluZ3NUYWcgICA9PT4gRGVwcmVjYXRlZCwgdXNlbGVzcwoqLwoKCl9jbXNUYWdQbHVnaW5DaHVua1R5cGUgX2Ntc1RhZ1BsdWdpbkNodW5rID0geyBOVUxMIH07CgoKLy8gRHVwbGljYXRlcyB0aGUgem9uZSBvZiBtZW1vcnkgdXNlZCBieSB0aGUgcGx1Zy1pbiBpbiB0aGUgbmV3IGNvbnRleHQKc3RhdGljCnZvaWQgRHVwVGFnTGlzdChzdHJ1Y3QgX2Ntc0NvbnRleHRfc3RydWN0KiBjdHgsIAogICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIHNyYykKewogICBfY21zVGFnUGx1Z2luQ2h1bmtUeXBlIG5ld0hlYWQgPSB7IE5VTEwgfTsKICAgX2Ntc1RhZ0xpbmtlZExpc3QqICBlbnRyeTsKICAgX2Ntc1RhZ0xpbmtlZExpc3QqICBBbnRlcmlvciA9IE5VTEw7CiAgIF9jbXNUYWdQbHVnaW5DaHVua1R5cGUqIGhlYWQgPSAoX2Ntc1RhZ1BsdWdpbkNodW5rVHlwZSopIHNyYy0+Y2h1bmtzW1RhZ1BsdWdpbl07CgogICAvLyBXYWxrIHRoZSBsaXN0IGNvcHlpbmcgYWxsIG5vZGVzCiAgIGZvciAoZW50cnkgPSBoZWFkLT5UYWc7CiAgICAgICBlbnRyeSAhPSBOVUxMOwogICAgICAgZW50cnkgPSBlbnRyeSAtPk5leHQpIHsKCiAgICAgICAgICAgX2Ntc1RhZ0xpbmtlZExpc3QgKm5ld0VudHJ5ID0gKCBfY21zVGFnTGlua2VkTGlzdCAqKSBfY21zU3ViQWxsb2NEdXAoY3R4IC0+TWVtUG9vbCwgZW50cnksIHNpemVvZihfY21zVGFnTGlua2VkTGlzdCkpOwoKICAgICAgICAgICBpZiAobmV3RW50cnkgPT0gTlVMTCkgCiAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgLy8gV2Ugd2FudCB0byBrZWVwIHRoZSBsaW5rZWQgbGlzdCBvcmRlciwgc28gdGhpcyBpcyBhIGxpdHRsZSBiaXQgdHJpY2t5CiAgICAgICAgICAgbmV3RW50cnkgLT4gTmV4dCA9IE5VTEw7CiAgICAgICAgICAgaWYgKEFudGVyaW9yKQogICAgICAgICAgICAgICBBbnRlcmlvciAtPiBOZXh0ID0gbmV3RW50cnk7CgogICAgICAgICAgIEFudGVyaW9yID0gbmV3RW50cnk7CgogICAgICAgICAgIGlmIChuZXdIZWFkLlRhZyA9PSBOVUxMKQogICAgICAgICAgICAgICBuZXdIZWFkLlRhZyA9IG5ld0VudHJ5OwogICB9CgogICBjdHggLT5jaHVua3NbVGFnUGx1Z2luXSA9IF9jbXNTdWJBbGxvY0R1cChjdHgtPk1lbVBvb2wsICZuZXdIZWFkLCBzaXplb2YoX2Ntc1RhZ1BsdWdpbkNodW5rVHlwZSkpOwp9Cgp2b2lkIF9jbXNBbGxvY1RhZ1BsdWdpbkNodW5rKHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIGN0eCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBfY21zQ29udGV4dF9zdHJ1Y3QqIHNyYykKewogICAgaWYgKHNyYyAhPSBOVUxMKSB7CgogICAgICAgIER1cFRhZ0xpc3QoY3R4LCBzcmMpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgc3RhdGljIF9jbXNUYWdQbHVnaW5DaHVua1R5cGUgVGFnUGx1Z2luQ2h1bmsgPSB7IE5VTEwgfTsKICAgICAgICBjdHggLT5jaHVua3NbVGFnUGx1Z2luXSA9IF9jbXNTdWJBbGxvY0R1cChjdHggLT5NZW1Qb29sLCAmVGFnUGx1Z2luQ2h1bmssIHNpemVvZihfY21zVGFnUGx1Z2luQ2h1bmtUeXBlKSk7CiAgICB9Cgp9CgpjbXNCb29sICBfY21zUmVnaXN0ZXJUYWdQbHVnaW4oY21zQ29udGV4dCBpZCwgY21zUGx1Z2luQmFzZSogRGF0YSkKewogICAgY21zUGx1Z2luVGFnKiBQbHVnaW4gPSAoY21zUGx1Z2luVGFnKikgRGF0YTsKICAgIF9jbXNUYWdMaW5rZWRMaXN0ICpwdDsKICAgIF9jbXNUYWdQbHVnaW5DaHVua1R5cGUqIFRhZ1BsdWdpbkNodW5rID0gKCBfY21zVGFnUGx1Z2luQ2h1bmtUeXBlKikgX2Ntc0NvbnRleHRHZXRDbGllbnRDaHVuayhpZCwgVGFnUGx1Z2luKTsKCiAgICBpZiAoRGF0YSA9PSBOVUxMKSB7CgogICAgICAgIFRhZ1BsdWdpbkNodW5rLT5UYWcgPSBOVUxMOwogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIHB0ID0gKF9jbXNUYWdMaW5rZWRMaXN0KikgX2Ntc1BsdWdpbk1hbGxvYyhpZCwgc2l6ZW9mKF9jbXNUYWdMaW5rZWRMaXN0KSk7CiAgICBpZiAocHQgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgIHB0IC0+U2lnbmF0dXJlICA9IFBsdWdpbiAtPlNpZ25hdHVyZTsKICAgIHB0IC0+RGVzY3JpcHRvciA9IFBsdWdpbiAtPkRlc2NyaXB0b3I7CiAgICBwdCAtPk5leHQgICAgICAgPSBUYWdQbHVnaW5DaHVuayAtPlRhZzsKCiAgICBUYWdQbHVnaW5DaHVuayAtPlRhZyA9IHB0OwogICAgCiAgICByZXR1cm4gVFJVRTsKfQoKLy8gUmV0dXJuIGEgZGVzY3JpcHRvciBmb3IgYSBnaXZlbiB0YWcgb3IgTlVMTApjbXNUYWdEZXNjcmlwdG9yKiBfY21zR2V0VGFnRGVzY3JpcHRvcihjbXNDb250ZXh0IENvbnRleHRJRCwgY21zVGFnU2lnbmF0dXJlIHNpZykKewogICAgX2Ntc1RhZ0xpbmtlZExpc3QqIHB0OwogICAgX2Ntc1RhZ1BsdWdpbkNodW5rVHlwZSogVGFnUGx1Z2luQ2h1bmsgPSAoIF9jbXNUYWdQbHVnaW5DaHVua1R5cGUqKSBfY21zQ29udGV4dEdldENsaWVudENodW5rKENvbnRleHRJRCwgVGFnUGx1Z2luKTsKCiAgICBmb3IgKHB0ID0gVGFnUGx1Z2luQ2h1bmstPlRhZzsKICAgICAgICAgICAgIHB0ICE9IE5VTEw7CiAgICAgICAgICAgICBwdCA9IHB0IC0+TmV4dCkgewoKICAgICAgICAgICAgICAgIGlmIChzaWcgPT0gcHQgLT4gU2lnbmF0dXJlKSByZXR1cm4gJnB0IC0+RGVzY3JpcHRvcjsKICAgIH0KCiAgICBmb3IgKHB0ID0gU3VwcG9ydGVkVGFnczsKICAgICAgICAgICAgcHQgIT0gTlVMTDsKICAgICAgICAgICAgcHQgPSBwdCAtPk5leHQpIHsKCiAgICAgICAgICAgICAgICBpZiAoc2lnID09IHB0IC0+IFNpZ25hdHVyZSkgcmV0dXJuICZwdCAtPkRlc2NyaXB0b3I7CiAgICB9CgogICAgcmV0dXJuIE5VTEw7Cn0K