Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBYUE0gTG9hZGVyIGFuZCBXcml0ZXIKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIFJ5YW4gUnVibGV5IChyeWFuQGxvc3RyZWFsaXR5Lm9yZykKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaWZkZWYgX01TQ19WRVIgCiNwcmFnbWEgd2FybmluZyAoZGlzYWJsZSA6IDQ3ODYpIC8vIGlkZW50aWZpZXIgd2FzIHRydW5jYXRlZCB0byAnbnVtYmVyJyBjaGFyYWN0ZXJzCiNlbmRpZgoKLy8gSU1QTEVNRU5UQVRJT04gTk9URVM6Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBJbml0aWFsIGRlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gYnkKLy8gLSBLYXJsLUhlaW56IEJ1c3NpYW4gKGtoYnVzc2lhbkBtb3NzLmRlKQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIENvbXBsZXRlbHkgcmV3cml0dGVuIGZyb20gc2NyYXRjaCBieSBSeWFuIFJ1YmxleSAocnlhbkBsb3N0cmVhbGl0eS5vcmcpCi8vIGluIG9yZGVyIHRvIGFkZHJlc3MgdGhlIGZvbGxvd2luZyBtYWpvciBmaXhlczoKLy8gKiBTdXBwb3J0cyBhbnkgbnVtYmVyIG9mIGNoYXJzIHBlciBwaXhlbCAobm90IGp1c3QgMSBvciAyKQovLyAqIEZpbGVzIHdpdGggMiBjaGFycyBwZXIgcGl4ZWwgYnV0IDw9IDI1NmNvbG9ycyBhcmUgbG9hZGVkIGFzIDI1NiBjb2xvciAobm90IDI0Yml0KQovLyAqIExvYWRzIG11Y2ggZmFzdGVyLCB1c2VzIG11Y2ggbGVzcyBtZW1vcnkKLy8gKiBzdXBwb3J0cyAjcmdiICNycnJnZ2diYmIgYW5kICNycnJyZ2dnZ2JiYmIgY29sb3JzIChub3QganVzdCAjcnJnZ2JiKQovLyAqIHN1cHBvcnRzIHN5bWJvbGljIGNvbG9yIG5hbWVzCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQbHVnaW4gSW50ZXJmYWNlCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0Kc3RhdGljIGludCBzX2Zvcm1hdF9pZDsKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gSW50ZXJuYWwgRnVuY3Rpb25zCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8vIHJlYWQgaW4gYW5kIHNraXAgYWxsIGp1bmsgdW50aWwgd2UgZmluZCBhIGNlcnRhaW4gY2hhcgpzdGF0aWMgQk9PTApGaW5kQ2hhcihGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIEJZVEUgbG9va19mb3IpIHsKCUJZVEUgYyA9ICdcMCc7Cglpby0+cmVhZF9wcm9jKCZjLCBzaXplb2YoQllURSksIDEsIGhhbmRsZSk7Cgl3aGlsZShjICE9IGxvb2tfZm9yKSB7CgkJaWYoIGlvLT5yZWFkX3Byb2MoJmMsIHNpemVvZihCWVRFKSwgMSwgaGFuZGxlKSAhPSAxICkKCQkJcmV0dXJuIEZBTFNFOwoJfQoJcmV0dXJuIFRSVUU7Cn0KCi8vIGZpbmQgc3RhcnQgb2Ygc3RyaW5nLCByZWFkIGRhdGEgdW50aWwgZW5kaW5nIHF1b3RlIGZvdW5kLCBhbGxvY2F0ZSBtZW1vcnkgYW5kIHJldHVybiBhIHN0cmluZwpzdGF0aWMgY2hhciAqClJlYWRTdHJpbmcoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlKSB7CglpZiggIUZpbmRDaGFyKGlvLCBoYW5kbGUsJyInKSApCgkJcmV0dXJuIE5VTEw7CglCWVRFIGM7CglzdGQ6OnN0cmluZyBzOwoJaW8tPnJlYWRfcHJvYygmYywgc2l6ZW9mKEJZVEUpLCAxLCBoYW5kbGUpOwoJd2hpbGUoYyAhPSAnIicpIHsKCQlzICs9IGM7CgkJaWYoIGlvLT5yZWFkX3Byb2MoJmMsIHNpemVvZihCWVRFKSwgMSwgaGFuZGxlKSAhPSAxICkKCQkJcmV0dXJuIE5VTEw7Cgl9CgljaGFyICpjc3RyID0gKGNoYXIgKiltYWxsb2Mocy5sZW5ndGgoKSsxKTsKCXN0cmNweShjc3RyLHMuY19zdHIoKSk7CglyZXR1cm4gY3N0cjsKfQoKc3RhdGljIGNoYXIgKgpCYXNlOTIodW5zaWduZWQgaW50IG51bSkgewoJc3RhdGljIGNoYXIgYjkyWzE2XTsgLy9lbm91Z2ggZm9yIG1vcmUgdGhlbiA2NCBiaXRzCglzdGF0aWMgY2hhciBkaWdpdFtdID0gIiAuWG9PK0AjJCUmKj0tOzo+LDwxMjM0NTY3ODkwcXdlcnR5dWlwYXNkZmdoamtsenhjdmJubU1OQlZDWkFTREZHSEpLTFBJVVlUUkVXUSF+Xi8oKV9gJ11be318IjsKCWI5MlsxNV0gPSAnXDAnOwoJaW50IGkgPSAxNDsKCWRvIHsKCQliOTJbaS0tXSA9IGRpZ2l0W251bSAlIDkyXTsKCQludW0gLz0gOTI7Cgl9IHdoaWxlKCBudW0gJiYgaSA+PSAwICk7CglyZXR1cm4gYjkyK2krMTsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQbHVnaW4gSW1wbGVtZW50YXRpb24KLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRm9ybWF0KCkgewoJcmV0dXJuICJYUE0iOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpEZXNjcmlwdGlvbigpIHsKCXJldHVybiAiWDExIFBpeG1hcCBGb3JtYXQiOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpFeHRlbnNpb24oKSB7CglyZXR1cm4gInhwbSI7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WClJlZ0V4cHIoKSB7CglyZXR1cm4gIl5bIFxcdF0qL1xcKiBYUE0gXFwqL1sgXFx0XSQiOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpNaW1lVHlwZSgpIHsKCXJldHVybiAiaW1hZ2UveC14cGl4bWFwIjsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClZhbGlkYXRlKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSkgewoJY2hhciBidWZmZXJbMjU2XTsKCgkvLyBjaGVja3MgdGhlIGZpcnN0IDI1NiBjaGFyYWN0ZXJzIGZvciB0aGUgbWFnaWMgc3RyaW5nCglpbnQgY291bnQgPSBpby0+cmVhZF9wcm9jKGJ1ZmZlciwgMSwgMjU2LCBoYW5kbGUpOwoJaWYoY291bnQgPD0gOSkgcmV0dXJuIEZBTFNFOwoJZm9yKGludCBpID0gMDsgaSA8IChjb3VudCAtIDkpOyBpKyspIHsKCQlpZihzdHJuY21wKCZidWZmZXJbaV0sICIvKiBYUE0gKi8iLCA5KSA9PSAwKQoJCQlyZXR1cm4gVFJVRTsKCX0KCXJldHVybiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClN1cHBvcnRzRXhwb3J0RGVwdGgoaW50IGRlcHRoKSB7CglyZXR1cm4gKAoJCQkoZGVwdGggPT0gOCkgfHwKCQkJKGRlcHRoID09IDI0KQoJCSk7Cn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OVgpTdXBwb3J0c0V4cG9ydFR5cGUoRlJFRV9JTUFHRV9UWVBFIHR5cGUpIHsKCXJldHVybiAodHlwZSA9PSBGSVRfQklUTUFQKSA/IFRSVUUgOiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClN1cHBvcnRzTm9QaXhlbHMoKSB7CglyZXR1cm4gVFJVRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIEZJQklUTUFQICogRExMX0NBTExDT05WCkxvYWQoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBpbnQgcGFnZSwgaW50IGZsYWdzLCB2b2lkICpkYXRhKSB7CgljaGFyIG1zZ1syNTZdOwogICAgRklCSVRNQVAgKmRpYiA9IE5VTEw7CgogICAgaWYgKCFoYW5kbGUpIHJldHVybiBOVUxMOwoKICAgIHRyeSB7CgkJY2hhciAqc3RyOwoJCQoJCUJPT0wgaGVhZGVyX29ubHkgPSAoZmxhZ3MgJiBGSUZfTE9BRF9OT1BJWEVMUykgPT0gRklGX0xPQURfTk9QSVhFTFM7CgkJCgkJLy9maW5kIHRoZSBzdGFydGluZyBicmFjZQoJCWlmKCAhRmluZENoYXIoaW8sIGhhbmRsZSwneycpICkKCQkJdGhyb3cgIkNvdWxkIG5vdCBmaW5kIHN0YXJ0aW5nIGJyYWNlIjsKCgkJLy9yZWFkIGluZm8gc3RyaW5nCgkJc3RyID0gUmVhZFN0cmluZyhpbywgaGFuZGxlKTsKCQlpZighc3RyKQoJCQl0aHJvdyAiRXJyb3IgcmVhZGluZyBpbmZvIHN0cmluZyI7CgoJCWludCB3aWR0aCwgaGVpZ2h0LCBjb2xvcnMsIGNwcDsKCQlpZiggc3NjYW5mKHN0ciwgIiVkICVkICVkICVkIiwgJndpZHRoLCAmaGVpZ2h0LCAmY29sb3JzLCAmY3BwKSAhPSA0ICkgewoJCQlmcmVlKHN0cik7CgkJCXRocm93ICJJbXByb3Blcmx5IGZvcm1lZCBpbmZvIHN0cmluZyI7CgkJfQoJCWZyZWUoc3RyKTsKCiAgICAgICAgaWYgKGNvbG9ycyA+IDI1NikgewoJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGVIZWFkZXIoaGVhZGVyX29ubHksIHdpZHRoLCBoZWlnaHQsIDI0LCBGSV9SR0JBX1JFRF9NQVNLLCBGSV9SR0JBX0dSRUVOX01BU0ssIEZJX1JHQkFfQkxVRV9NQVNLKTsKCQl9IGVsc2UgewoJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGVIZWFkZXIoaGVhZGVyX29ubHksIHdpZHRoLCBoZWlnaHQsIDgpOwoJCX0KCgkJLy9idWlsZCBhIG1hcCBvZiBjb2xvciBjaGFycyB0byByZ2IgdmFsdWVzCgkJc3RkOjptYXA8c3RkOjpzdHJpbmcsRklMRV9SR0JBPiByYXdwYWw7IC8vd2lsbCBzdG9yZSBpbmRleCBpbiBBbHBoYSBpZiA4YnBwCgkJZm9yKGludCBpID0gMDsgaSA8IGNvbG9yczsgaSsrICkgewoJCQlGSUxFX1JHQkEgcmdiYTsKCgkJCXN0ciA9IFJlYWRTdHJpbmcoaW8sIGhhbmRsZSk7CgkJCWlmKCFzdHIpCgkJCQl0aHJvdyAiRXJyb3IgcmVhZGluZyBjb2xvciBzdHJpbmdzIjsKCgkJCXN0ZDo6c3RyaW5nIGNocnMoc3RyLGNwcCk7IC8vY3JlYXRlIGEgc3RyaW5nIGZvciB0aGUgY29sb3IgY2hhcnMgdXNpbmcgdGhlIGZpcnN0IGNwcCBjaGFycwoJCQljaGFyICprZXlzID0gc3RyICsgY3BwOyAvL3RoZSBjb2xvciBrZXlzIGZvciB0aGVzZSBjaGFycyBzdGFydCBhZnRlciB0aGUgZmlyc3QgY3BwIGNoYXJzCgoJCQkvL3RyYW5zbGF0ZSBhbGwgdGhlIHRhYnMgdG8gc3BhY2VzCgkJCWNoYXIgKnRtcCA9IGtleXM7CgkJCXdoaWxlKCBzdHJjaHIodG1wLCdcdCcpICkgewoJCQkJdG1wID0gc3RyY2hyKHRtcCwnXHQnKTsKCQkJCSp0bXArKyA9ICcgJzsKCQkJfQoKCQkJLy9wcmVmZXIgdGhlIGNvbG9yIHZpc3VhbAoJCQlpZiggc3Ryc3RyKGtleXMsIiBjICIpICkgewoJCQkJY2hhciAqY2xyID0gc3Ryc3RyKGtleXMsIiBjICIpICsgMzsKCQkJCXdoaWxlKCAqY2xyID09ICcgJyApIGNscisrOyAvL2ZpbmQgdGhlIHN0YXJ0IG9mIHRoZSBoZXggcmdiIHZhbHVlCgkJCQlpZiggKmNsciA9PSAnIycgKSB7CgkJCQkJaW50IHJlZCA9IDAsIGdyZWVuID0gMCwgYmx1ZSA9IDAsIG47CgkJCQkJY2xyKys7CgkJCQkJLy9lbmQgc3RyaW5nIGF0IGZpcnN0IHNwYWNlLCBpZiBhbnkgZm91bmQKCQkJCQlpZiggc3RyY2hyKGNsciwnICcpICkKCQkJCQkJKihzdHJjaHIoY2xyLCcgJykpID0gJ1wwJzsKCQkJCQkvL3BhcnNlIGhleCBjb2xvciwgaXQgY2FuIGJlICNyZ2IgI3JyZ2diYiAjcnJyZ2dnYmJiIG9yICNycnJyZ2dnZ2JiYmIKCQkJCQlzd2l0Y2goIHN0cmxlbihjbHIpICkgewoJCQkJCQljYXNlIDM6CW4gPSBzc2NhbmYoY2xyLCIlMDF4JTAxeCUwMXgiLCZyZWQsJmdyZWVuLCZibHVlKTsKCQkJCQkJCXJlZCB8PSAocmVkIDw8IDQpOwoJCQkJCQkJZ3JlZW4gfD0gKGdyZWVuIDw8IDQpOwoJCQkJCQkJYmx1ZSB8PSAoYmx1ZSA8PCA0KTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlIDY6CW4gPSBzc2NhbmYoY2xyLCIlMDJ4JTAyeCUwMngiLCZyZWQsJmdyZWVuLCZibHVlKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlIDk6CW4gPSBzc2NhbmYoY2xyLCIlMDN4JTAzeCUwM3giLCZyZWQsJmdyZWVuLCZibHVlKTsKCQkJCQkJCXJlZCA+Pj0gNDsKCQkJCQkJCWdyZWVuID4+PSA0OwoJCQkJCQkJYmx1ZSA+Pj0gNDsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlIDEyOiBuID0gc3NjYW5mKGNsciwiJTA0eCUwNHglMDR4IiwmcmVkLCZncmVlbiwmYmx1ZSk7CgkJCQkJCQlyZWQgPj49IDg7CgkJCQkJCQlncmVlbiA+Pj0gODsKCQkJCQkJCWJsdWUgPj49IDg7CgkJCQkJCQlicmVhazsKCQkJCQkJZGVmYXVsdDoKCQkJCQkJCW4gPSAwOwoJCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCWlmKCBuICE9IDMgKSB7CgkJCQkJCWZyZWUoc3RyKTsKCQkJCQkJdGhyb3cgIkltcHJvcGVybHkgZm9ybWVkIGhleCBjb2xvciB2YWx1ZSI7CgkJCQkJfQoJCQkJCXJnYmEuciA9IChCWVRFKXJlZDsKCQkJCQlyZ2JhLmcgPSAoQllURSlncmVlbjsKCQkJCQlyZ2JhLmIgPSAoQllURSlibHVlOwoJCQkJfSBlbHNlIGlmKCAhc3RybmNtcChjbHIsIk5vbmUiLDQpIHx8ICFzdHJuY21wKGNsciwibm9uZSIsNCkgKSB7CgkJCQkJcmdiYS5yID0gcmdiYS5nID0gcmdiYS5iID0gMHhGRjsKCQkJCX0gZWxzZSB7CgkJCQkJY2hhciAqdG1wID0gY2xyOwoKCQkJCQkvL3NjYW4gZm9yd2FyZCBmb3IgZWFjaCBzcGFjZSwgaWYgaXRzICIgeCAiIG9yICIgeHggIiBlbmQgdGhlIHN0cmluZyB0aGVyZQoJCQkJCS8vdGhpcyBtZWFucyBpdHMgcHJvYmFibHkgc29tZSBvdGhlciB2aXN1YWwgZGF0YSBiZXlvbmQgdGhhdCBwb2ludCBhbmQgbm90CgkJCQkJLy9wYXJ0IG9mIHRoZSBjb2xvciBuYW1lLiAgSG93IG1hbnkgbmFtZWQgY29sb3IgZW5kIHdpdGggYSAxIG9yIDIgY2hhcmFjdGVyCgkJCQkJLy93b3JkPyBQcm9iYWJseSBub25lIGluIG91ciBsaXN0IGF0IGxlYXN0LgoJCQkJCXdoaWxlKCAodG1wID0gc3RyY2hyKHRtcCwnICcpKSAhPSBOVUxMICkgewoJCQkJCQlpZiggdG1wWzFdICE9ICcgJyApIHsKCQkJCQkJCWlmKCAodG1wWzJdID09ICcgJykgfHwgKHRtcFsyXSAhPSAnICcgJiYgdG1wWzNdID09ICcgJykgKSB7CgkJCQkJCQkJdG1wWzBdID0gJ1wwJzsKCQkJCQkJCQlicmVhazsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQl0bXArKzsKCQkJCQl9CgoJCQkJCS8vcmVtb3ZlIGFueSB0cmFpbGluZyBzcGFjZXMKCQkJCQl0bXAgPSBjbHIrc3RybGVuKGNsciktMTsKCQkJCQl3aGlsZSggKnRtcCA9PSAnICcgKSB7CgkJCQkJCSp0bXAgPSAnXDAnOwoJCQkJCQl0bXAtLTsKCQkJCQl9CgoJCQkJCWlmICghRnJlZUltYWdlX0xvb2t1cFgxMUNvbG9yKGNsciwgICZyZ2JhLnIsICZyZ2JhLmcsICZyZ2JhLmIpKSB7CgkJCQkJCXNwcmludGYobXNnLCAiVW5rbm93biBjb2xvciBuYW1lICclcyciLCBzdHIpOwoJCQkJCQlmcmVlKHN0cik7CgkJCQkJCXRocm93IG1zZzsKCQkJCQl9CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlmcmVlKHN0cik7CgkJCQl0aHJvdyAiT25seSBjb2xvciB2aXN1YWxzIGFyZSBzdXBwb3J0ZWQiOwoJCQl9CgoJCQkvL2FkZCBjb2xvciB0byBtYXAKCQkJcmdiYS5hID0gKEJZVEUpKChjb2xvcnMgPiAyNTYpID8gMCA6IGkpOwoJCQlyYXdwYWxbY2hyc10gPSByZ2JhOwoKCQkJLy9idWlsZCBwYWxldHRlIGlmIG5lZWRlZAoJCQlpZiggY29sb3JzIDw9IDI1NiApIHsKCQkJCVJHQlFVQUQgKnBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgkJCQlwYWxbaV0ucmdiQmx1ZSA9IHJnYmEuYjsKCQkJCXBhbFtpXS5yZ2JHcmVlbiA9IHJnYmEuZzsKCQkJCXBhbFtpXS5yZ2JSZWQgPSByZ2JhLnI7CgkJCX0KCgkJCWZyZWUoc3RyKTsKCQl9CgkJLy9kb25lIHBhcnNpbmcgY29sb3IgbWFwCgoJCWlmKGhlYWRlcl9vbmx5KSB7CgkJCS8vIGhlYWRlciBvbmx5IG1vZGUKCQkJcmV0dXJuIGRpYjsKCQl9CgoJCS8vcmVhZCBpbiBwaXhlbCBkYXRhCgkJZm9yKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrICkgewoJCQlCWVRFICpsaW5lID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0geSAtIDEpOwoJCQlzdHIgPSBSZWFkU3RyaW5nKGlvLCBoYW5kbGUpOwoJCQlpZighc3RyKQoJCQkJdGhyb3cgIkVycm9yIHJlYWRpbmcgcGl4ZWwgc3RyaW5ncyI7CgkJCWNoYXIgKnBpeGVsX3B0ciA9IHN0cjsKCgkJCWZvcihpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewoJCQkJLy9sb2NhdGUgdGhlIGNoYXJzIGluIHRoZSBjb2xvciBtYXAKCQkJCXN0ZDo6c3RyaW5nIGNocnMocGl4ZWxfcHRyLGNwcCk7CgkJCQlGSUxFX1JHQkEgcmdiYSA9IHJhd3BhbFtjaHJzXTsKCgkJCQlpZiggY29sb3JzID4gMjU2ICkgewoJCQkJCWxpbmVbRklfUkdCQV9CTFVFXSA9IHJnYmEuYjsKCQkJCQlsaW5lW0ZJX1JHQkFfR1JFRU5dID0gcmdiYS5nOwoJCQkJCWxpbmVbRklfUkdCQV9SRURdID0gcmdiYS5yOwoJCQkJCWxpbmUgKz0gMzsKCQkJCX0gZWxzZSB7CgkJCQkJKmxpbmUgPSByZ2JhLmE7CgkJCQkJbGluZSsrOwoJCQkJfQoKCQkJCXBpeGVsX3B0ciArPSBjcHA7CgkJCX0KCgkJCWZyZWUoc3RyKTsKCQl9CgkJLy9kb25lIHJlYWRpbmcgcGl4ZWwgZGF0YQoKCQlyZXR1cm4gZGliOwoJfSBjYXRjaChjb25zdCBjaGFyICp0ZXh0KSB7CiAgICAgICBGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2Moc19mb3JtYXRfaWQsIHRleHQpOwoKICAgICAgIGlmKCBkaWIgIT0gTlVMTCApCiAgICAgICAgICAgRnJlZUltYWdlX1VubG9hZChkaWIpOwoKICAgICAgIHJldHVybiBOVUxMOwogICAgfQp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKU2F2ZShGcmVlSW1hZ2VJTyAqaW8sIEZJQklUTUFQICpkaWIsIGZpX2hhbmRsZSBoYW5kbGUsIGludCBwYWdlLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEpIHsKCWlmICgoZGliICE9IE5VTEwpICYmIChoYW5kbGUgIT0gTlVMTCkpIHsKCQljaGFyIGhlYWRlcltdID0gIi8qIFhQTSAqL1xuc3RhdGljIGNoYXIgKmZyZWVpbWFnZVtdID0ge1xuLyogd2lkdGggaGVpZ2h0IG51bV9jb2xvcnMgY2hhcnNfcGVyX3BpeGVsICovXG5cIiIsCgkJc3RhcnRfY29sb3JzW10gPSAiXCIsXG4vKiBjb2xvcnMgKi9cblwiIiwKCQlzdGFydF9waXhlbHNbXSA9ICJcIixcbi8qIHBpeGVscyAqL1xuXCIiLAoJCW5ld19saW5lW10gPSAiXCIsXG5cIiIsCgkJZm9vdGVyW10gPSAiXCJcbn07XG4iLAoJCWJ1ZlsyNTZdOyAvLzI1NiBpcyBtb3JlIHRoZW4gZW5vdWdoIHRvIHNwcmludGYgNCBpbnRzIGludG8sIG9yIHRoZSBiYXNlLTkyIGNoYXJzIGFuZCAjcnJnZ2JiIGxpbmUKCgkJaWYoIGlvLT53cml0ZV9wcm9jKGhlYWRlciwgKHVuc2lnbmVkIGludClzdHJsZW4oaGVhZGVyKSwgMSwgaGFuZGxlKSAhPSAxICkKCQkJcmV0dXJuIEZBTFNFOwoKCQlpbnQgd2lkdGggPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKSwgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChkaWIpLCBicHAgPSBGcmVlSW1hZ2VfR2V0QlBQKGRpYik7CgkJUkdCUVVBRCAqcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCQlpbnQgeCx5OwoKCQkvL21hcCBiYXNlOTIgY2hycyB0byB0aGUgcmdiIHZhbHVlIHRvIGNyZWF0ZSB0aGUgcGFsZXR0ZQoJCXN0ZDo6bWFwPERXT1JELEZJTEVfUkdCPiBjaHJzMmNvbG9yOwoJCS8vbWFwIDhicHAgaW5kZXggb3IgMjRicHAgcmdiIHZhbHVlIHRvIHRoZSBiYXNlOTIgY2hycyB0byBjcmVhdGUgcGl4ZWwgZGF0YQoJCXR5cGVkZWYgdW5pb24gewoJCQlEV09SRCBpbmRleDsKCQkJRklMRV9SR0JBIHJnYmE7CgkJfSBEV09SRFJHQkE7CgkJc3RkOjptYXA8RFdPUkQsc3RkOjpzdHJpbmc+IGNvbG9yMmNocnM7CgoJCS8vbG9vcCB0aHJ1IGVudGlyZSBkaWIsIGlmIG5ldyBjb2xvciwgaW5jIG51bV9jb2xvcnMgYW5kIGFkZCB0byBib3RoIG1hcHMKCQlpbnQgbnVtX2NvbG9ycyA9IDA7CgkJZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KysgKSB7CgkJCUJZVEUgKmxpbmUgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSB5IC0gMSk7CgkJCWZvcih4ID0gMDsgeCA8IHdpZHRoOyB4KysgKSB7CgkJCQlGSUxFX1JHQiByZ2I7CgkJCQlEV09SRFJHQkEgdTsKCQkJCWlmKCBicHAgPiA4ICkgewoJCQkJCXUucmdiYS5iID0gcmdiLmIgPSBsaW5lW0ZJX1JHQkFfQkxVRV07CgkJCQkJdS5yZ2JhLmcgPSByZ2IuZyA9IGxpbmVbRklfUkdCQV9HUkVFTl07CgkJCQkJdS5yZ2JhLnIgPSByZ2IuciA9IGxpbmVbRklfUkdCQV9SRURdOwoJCQkJCXUucmdiYS5hID0gMDsKCQkJCQlsaW5lICs9IDM7CgkJCQl9IGVsc2UgewoJCQkJCXUuaW5kZXggPSAqbGluZTsKCQkJCQlyZ2IuYiA9IHBhbFt1LmluZGV4XS5yZ2JCbHVlOwoJCQkJCXJnYi5nID0gcGFsW3UuaW5kZXhdLnJnYkdyZWVuOwoJCQkJCXJnYi5yID0gcGFsW3UuaW5kZXhdLnJnYlJlZDsKCQkJCQlsaW5lKys7CgkJCQl9CgkJCQlpZiggY29sb3IyY2hycy5maW5kKHUuaW5kZXgpID09IGNvbG9yMmNocnMuZW5kKCkgKSB7IC8vbmV3IGNvbG9yCgkJCQkJc3RkOjpzdHJpbmcgY2hycyhCYXNlOTIobnVtX2NvbG9ycykpOwoJCQkJCWNvbG9yMmNocnNbdS5pbmRleF0gPSBjaHJzOwoJCQkJCWNocnMyY29sb3JbbnVtX2NvbG9yc10gPSByZ2I7CgkJCQkJbnVtX2NvbG9ycysrOwoJCQkJfQoJCQl9CgkJfQoKCQlpbnQgY3BwID0gKGludCkobG9nKChkb3VibGUpbnVtX2NvbG9ycykvbG9nKDkyLjApKSArIDE7CgoJCXNwcmludGYoYnVmLCAiJWQgJWQgJWQgJWQiLCBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKSwgRnJlZUltYWdlX0dldEhlaWdodChkaWIpLCBudW1fY29sb3JzLCBjcHAgKTsKCQlpZiggaW8tPndyaXRlX3Byb2MoYnVmLCAodW5zaWduZWQgaW50KXN0cmxlbihidWYpLCAxLCBoYW5kbGUpICE9IDEgKQoJCQlyZXR1cm4gRkFMU0U7CgoJCWlmKCBpby0+d3JpdGVfcHJvYyhzdGFydF9jb2xvcnMsICh1bnNpZ25lZCBpbnQpc3RybGVuKHN0YXJ0X2NvbG9ycyksIDEsIGhhbmRsZSkgIT0gMSApCgkJCXJldHVybiBGQUxTRTsKCgkJLy93cml0ZSBjb2xvcnMsIHVzaW5nIG1hcCBvZiBjaHJzLT5yZ2IKCQlmb3IoeCA9IDA7IHggPCBudW1fY29sb3JzOyB4KysgKSB7CgkJCXNwcmludGYoYnVmLCAiJSpzIGMgIyUwMnglMDJ4JTAyeCIsIGNwcCwgQmFzZTkyKHgpLCBjaHJzMmNvbG9yW3hdLnIsIGNocnMyY29sb3JbeF0uZywgY2hyczJjb2xvclt4XS5iICk7CgkJCWlmKCBpby0+d3JpdGVfcHJvYyhidWYsICh1bnNpZ25lZCBpbnQpc3RybGVuKGJ1ZiksIDEsIGhhbmRsZSkgIT0gMSApCgkJCQlyZXR1cm4gRkFMU0U7CgkJCWlmKCB4ID09IG51bV9jb2xvcnMgLSAxICkgewoJCQkJaWYoIGlvLT53cml0ZV9wcm9jKHN0YXJ0X3BpeGVscywgKHVuc2lnbmVkIGludClzdHJsZW4oc3RhcnRfcGl4ZWxzKSwgMSwgaGFuZGxlKSAhPSAxICkKCQkJCQlyZXR1cm4gRkFMU0U7CgkJCX0gZWxzZSB7CgkJCQlpZiggaW8tPndyaXRlX3Byb2MobmV3X2xpbmUsICh1bnNpZ25lZCBpbnQpc3RybGVuKG5ld19saW5lKSwgMSwgaGFuZGxlKSAhPSAxICkKCQkJCQlyZXR1cm4gRkFMU0U7CgkJCX0KCQl9CgoKCQkvL3dyaXRlIHBpeGVscywgdXNpbmcgbWFwIG9mIHJnYihpZiAyNGJwcCkgb3IgaW5kZXgoaWYgOGJwcCktPmNocnMKCQlmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKyApIHsKCQkJQllURSAqbGluZSA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhlaWdodCAtIHkgLSAxKTsKCQkJZm9yKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKCQkJCURXT1JEUkdCQSB1OwoJCQkJaWYoIGJwcCA+IDggKSB7CgkJCQkJdS5yZ2JhLmIgPSBsaW5lW0ZJX1JHQkFfQkxVRV07CgkJCQkJdS5yZ2JhLmcgPSBsaW5lW0ZJX1JHQkFfR1JFRU5dOwoJCQkJCXUucmdiYS5yID0gbGluZVtGSV9SR0JBX1JFRF07CgkJCQkJdS5yZ2JhLmEgPSAwOwoJCQkJCWxpbmUgKz0gMzsKCQkJCX0gZWxzZSB7CgkJCQkJdS5pbmRleCA9ICpsaW5lOwoJCQkJCWxpbmUrKzsKCQkJCX0KCQkJCXNwcmludGYoYnVmLCAiJSpzIiwgY3BwLCAoY2hhciAqKWNvbG9yMmNocnNbdS5pbmRleF0uY19zdHIoKSk7CgkJCQlpZiggaW8tPndyaXRlX3Byb2MoYnVmLCBjcHAsIDEsIGhhbmRsZSkgIT0gMSApCgkJCQkJcmV0dXJuIEZBTFNFOwoJCQl9CgkJCWlmKCB5ID09IGhlaWdodCAtIDEgKSB7CgkJCQlpZiggaW8tPndyaXRlX3Byb2MoZm9vdGVyLCAodW5zaWduZWQgaW50KXN0cmxlbihmb290ZXIpLCAxLCBoYW5kbGUpICE9IDEgKQoJCQkJCXJldHVybiBGQUxTRTsKCQkJfSBlbHNlIHsKCQkJCWlmKCBpby0+d3JpdGVfcHJvYyhuZXdfbGluZSwgKHVuc2lnbmVkIGludClzdHJsZW4obmV3X2xpbmUpLCAxLCBoYW5kbGUpICE9IDEgKQoJCQkJCXJldHVybiBGQUxTRTsKCQkJfQoJCX0KCgkJcmV0dXJuIFRSVUU7Cgl9IGVsc2UgewoJCXJldHVybiBGQUxTRTsKCX0KfQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyAgIEluaXQKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKdm9pZCBETExfQ0FMTENPTlYKSW5pdFhQTShQbHVnaW4gKnBsdWdpbiwgaW50IGZvcm1hdF9pZCkKewogICAgc19mb3JtYXRfaWQgPSBmb3JtYXRfaWQ7CgoJcGx1Z2luLT5mb3JtYXRfcHJvYyA9IEZvcm1hdDsKCXBsdWdpbi0+ZGVzY3JpcHRpb25fcHJvYyA9IERlc2NyaXB0aW9uOwoJcGx1Z2luLT5leHRlbnNpb25fcHJvYyA9IEV4dGVuc2lvbjsKCXBsdWdpbi0+cmVnZXhwcl9wcm9jID0gUmVnRXhwcjsKCXBsdWdpbi0+b3Blbl9wcm9jID0gTlVMTDsKCXBsdWdpbi0+Y2xvc2VfcHJvYyA9IE5VTEw7CglwbHVnaW4tPnBhZ2Vjb3VudF9wcm9jID0gTlVMTDsKCXBsdWdpbi0+cGFnZWNhcGFiaWxpdHlfcHJvYyA9IE5VTEw7CglwbHVnaW4tPmxvYWRfcHJvYyA9IExvYWQ7CglwbHVnaW4tPnNhdmVfcHJvYyA9IFNhdmU7CglwbHVnaW4tPnZhbGlkYXRlX3Byb2MgPSBWYWxpZGF0ZTsKCXBsdWdpbi0+bWltZV9wcm9jID0gTWltZVR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF9icHBfcHJvYyA9IFN1cHBvcnRzRXhwb3J0RGVwdGg7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF90eXBlX3Byb2MgPSBTdXBwb3J0c0V4cG9ydFR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2ljY19wcm9maWxlc19wcm9jID0gTlVMTDsKCXBsdWdpbi0+c3VwcG9ydHNfbm9fcGl4ZWxzX3Byb2MgPSBTdXBwb3J0c05vUGl4ZWxzOwp9Cgo=