Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQTk0gKFBQTSwgUEdNLCBQQk0pIExvYWRlciBhbmQgV3JpdGVyCi8vCi8vIERlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gYnkKLy8gLSBGbG9yaXMgdmFuIGRlbiBCZXJnIChmbHZkYmVyZ0B3eHMubmwpCi8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gSW50ZXJuYWwgZnVuY3Rpb25zCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKgpHZXQgYW4gaW50ZWdlciB2YWx1ZSBmcm9tIHRoZSBhY3R1YWwgcG9zaXRpb24gcG9pbnRlZCBieSBoYW5kbGUKKi8Kc3RhdGljIGludApHZXRJbnQoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlKSB7CiAgICBjaGFyIGMgPSAwOwoJQk9PTCBiRmlyc3RDaGFyOwoKICAgIC8vIHNraXAgZm9yd2FyZCB0byBzdGFydCBvZiBuZXh0IG51bWJlcgoKCWlmKCFpby0+cmVhZF9wcm9jKCZjLCAxLCAxLCBoYW5kbGUpKSB7CgkJdGhyb3cgRklfTVNHX0VSUk9SX1BBUlNJTkc7Cgl9CgogICAgd2hpbGUgKDEpIHsKICAgICAgICAvLyBlYXQgY29tbWVudHMKCiAgICAgICAgaWYgKGMgPT0gJyMnKSB7CgkJCS8vIGlmIHdlJ3JlIGF0IGEgY29tbWVudCwgcmVhZCB0byBlbmQgb2YgbGluZQoKICAgICAgICAgICAgYkZpcnN0Q2hhciA9IFRSVUU7CgogICAgICAgICAgICB3aGlsZSAoMSkgewoJCQkJaWYoIWlvLT5yZWFkX3Byb2MoJmMsIDEsIDEsIGhhbmRsZSkpIHsKCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfUEFSU0lORzsKCQkJCX0KCgkJCQlpZiAoYkZpcnN0Q2hhciAmJiBjID09ICcgJykgewoJCQkJCS8vIGxvb3Agb2ZmIDEgc3AgYWZ0ZXIgIwoJCQkJCWJGaXJzdENoYXIgPSBGQUxTRTsKCQkJCX0gZWxzZSBpZiAoYyA9PSAnXG4nKSB7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgogICAgICAgIGlmIChjID49ICcwJyAmJiBjIDw9JzknKSB7CgkJCS8vIHdlJ3ZlIGZvdW5kIHdoYXQgd2Ugd2VyZSBsb29raW5nIGZvcgogICAgICAgICAgICBicmVhazsKCQl9CgoJCWlmKCFpby0+cmVhZF9wcm9jKCZjLCAxLCAxLCBoYW5kbGUpKSB7CgkJCXRocm93IEZJX01TR19FUlJPUl9QQVJTSU5HOwoJCX0KICAgIH0KCiAgICAvLyB3ZSdyZSBhdCB0aGUgc3RhcnQgb2YgYSBudW1iZXIsIGNvbnRpbnVlIHVudGlsIHdlIGhpdCBhIG5vbi1udW1iZXIKCiAgICBpbnQgaSA9IDA7CgogICAgd2hpbGUgKDEpIHsKICAgICAgICBpID0gKGkgKiAxMCkgKyAoYyAtICcwJyk7CgoJCWlmKCFpby0+cmVhZF9wcm9jKCZjLCAxLCAxLCBoYW5kbGUpKSB7CgkJCXRocm93IEZJX01TR19FUlJPUl9QQVJTSU5HOwoJCX0KCgkJaWYgKGMgPCAnMCcgfHwgYyA+ICc5JykgewoJCQlicmVhazsKCQl9CiAgICB9CgogICAgcmV0dXJuIGk7Cn0KCi8qKgpSZWFkIGEgV09SRCB2YWx1ZSB0YWtpbmcgaW50byBhY2NvdW50IHRoZSBlbmRpYW5lc3MgaXNzdWUKKi8Kc3RhdGljIGlubGluZSBXT1JEIApSZWFkV29yZChGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUpIHsKCVdPUkQgbGV2ZWwgPSAwOwoJaW8tPnJlYWRfcHJvYygmbGV2ZWwsIDIsIDEsIGhhbmRsZSk7IAojaWZuZGVmIEZSRUVJTUFHRV9CSUdFTkRJQU4KCVN3YXBTaG9ydCgmbGV2ZWwpOwkvLyBQTk0gdXNlcyB0aGUgYmlnIGVuZGlhbiBjb252ZW50aW9uCiNlbmRpZgoJcmV0dXJuIGxldmVsOwp9CgovKioKV3JpdGUgYSBXT1JEIHZhbHVlIHRha2luZyBpbnRvIGFjY291bnQgdGhlIGVuZGlhbmVzcyBpc3N1ZQoqLwpzdGF0aWMgaW5saW5lIHZvaWQgCldyaXRlV29yZChGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIGNvbnN0IFdPUkQgdmFsdWUpIHsKCVdPUkQgbGV2ZWwgPSB2YWx1ZTsKI2lmbmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCglTd2FwU2hvcnQoJmxldmVsKTsJLy8gUE5NIHVzZXMgdGhlIGJpZyBlbmRpYW4gY29udmVudGlvbgojZW5kaWYKCWlvLT53cml0ZV9wcm9jKCZsZXZlbCwgMiwgMSwgaGFuZGxlKTsKfQoKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gUGx1Z2luIEludGVyZmFjZQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpzdGF0aWMgaW50IHNfZm9ybWF0X2lkOwoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQbHVnaW4gSW1wbGVtZW50YXRpb24KLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRm9ybWF0KCkgewoJcmV0dXJuICJQTk0iOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpEZXNjcmlwdGlvbigpIHsKCXJldHVybiAiUG9ydGFibGUgTmV0d29yayBNZWRpYSI7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCkV4dGVuc2lvbigpIHsKCXJldHVybiAicGJtLHBnbSxwcG0iOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpSZWdFeHByKCkgewoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCk1pbWVUeXBlKCkgewoJcmV0dXJuICJpbWFnZS9mcmVlaW1hZ2UtcG5tIjsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClZhbGlkYXRlKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSkgewoJQllURSBwYm1faWQxW10gPSB7IDB4NTAsIDB4MzEgfTsKCUJZVEUgcGJtX2lkMltdID0geyAweDUwLCAweDM0IH07CglCWVRFIHBnbV9pZDFbXSA9IHsgMHg1MCwgMHgzMiB9OwoJQllURSBwZ21faWQyW10gPSB7IDB4NTAsIDB4MzUgfTsKCUJZVEUgcHBtX2lkMVtdID0geyAweDUwLCAweDMzIH07CglCWVRFIHBwbV9pZDJbXSA9IHsgMHg1MCwgMHgzNiB9OwoJQllURSBzaWduYXR1cmVbMl0gPSB7IDAsIDAgfTsKCglpby0+cmVhZF9wcm9jKHNpZ25hdHVyZSwgMSwgc2l6ZW9mKHBibV9pZDEpLCBoYW5kbGUpOwoKCWlmIChtZW1jbXAocGJtX2lkMSwgc2lnbmF0dXJlLCBzaXplb2YocGJtX2lkMSkpID09IDApCgkJcmV0dXJuIFRSVUU7CgoJaWYgKG1lbWNtcChwYm1faWQyLCBzaWduYXR1cmUsIHNpemVvZihwYm1faWQyKSkgPT0gMCkKCQlyZXR1cm4gVFJVRTsKCglpZiAobWVtY21wKHBnbV9pZDEsIHNpZ25hdHVyZSwgc2l6ZW9mKHBnbV9pZDEpKSA9PSAwKQoJCXJldHVybiBUUlVFOwoKCWlmIChtZW1jbXAocGdtX2lkMiwgc2lnbmF0dXJlLCBzaXplb2YocGdtX2lkMikpID09IDApCgkJcmV0dXJuIFRSVUU7CgoJaWYgKG1lbWNtcChwcG1faWQxLCBzaWduYXR1cmUsIHNpemVvZihwcG1faWQxKSkgPT0gMCkKCQlyZXR1cm4gVFJVRTsKCglpZiAobWVtY21wKHBwbV9pZDIsIHNpZ25hdHVyZSwgc2l6ZW9mKHBwbV9pZDIpKSA9PSAwKQoJCXJldHVybiBUUlVFOwoKCXJldHVybiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClN1cHBvcnRzRXhwb3J0RGVwdGgoaW50IGRlcHRoKSB7CglyZXR1cm4gKAoJCQkoZGVwdGggPT0gMSkgfHwKCQkJKGRlcHRoID09IDgpIHx8CgkJCShkZXB0aCA9PSAyNCkKCQkpOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYgClN1cHBvcnRzRXhwb3J0VHlwZShGUkVFX0lNQUdFX1RZUEUgdHlwZSkgewoJcmV0dXJuICgKCQkodHlwZSA9PSBGSVRfQklUTUFQKSAgfHwKCQkodHlwZSA9PSBGSVRfVUlOVDE2KSAgfHwKCQkodHlwZSA9PSBGSVRfUkdCMTYpCgkpOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKU3VwcG9ydHNOb1BpeGVscygpIHsKCXJldHVybiBUUlVFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgRklCSVRNQVAgKiBETExfQ0FMTENPTlYKTG9hZChGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIGludCBwYWdlLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEpIHsKCWNoYXIgaWRfb25lID0gMCwgaWRfdHdvID0gMDsKCWludCB4LCB5OwoJRklCSVRNQVAgKmRpYiA9IE5VTEw7CglSR0JRVUFEICpwYWw7CS8vIHBvaW50ZXIgdG8gZGliIHBhbGV0dGUKCWludCBpOwoKCWlmICghaGFuZGxlKSB7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJQk9PTCBoZWFkZXJfb25seSA9IChmbGFncyAmIEZJRl9MT0FEX05PUElYRUxTKSA9PSBGSUZfTE9BRF9OT1BJWEVMUzsKCgl0cnkgewoJCUZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlID0gRklUX0JJVE1BUDsJLy8gc3RhbmRhcmQgaW1hZ2U6IDEtLCA4LSwgMjQtYml0CgoJCS8vIFJlYWQgdGhlIGZpcnN0IHR3byBieXRlcyBvZiB0aGUgZmlsZSB0byBkZXRlcm1pbmUgdGhlIGZpbGUgZm9ybWF0CgkJLy8gIlAxIiA9IGFzY2lpIGJpdG1hcCwgIlAyIiA9IGFzY2lpIGdyZXltYXAsICJQMyIgPSBhc2NpaSBwaXhtYXAsCgkJLy8gIlA0IiA9IHJhdyBiaXRtYXAsICJQNSIgPSByYXcgZ3JleW1hcCwgIlA2IiA9IHJhdyBwaXhtYXAKCgkJaW8tPnJlYWRfcHJvYygmaWRfb25lLCAxLCAxLCBoYW5kbGUpOwoJCWlvLT5yZWFkX3Byb2MoJmlkX3R3bywgMSwgMSwgaGFuZGxlKTsKCgkJaWYgKChpZF9vbmUgIT0gJ1AnKSB8fCAoaWRfdHdvIDwgJzEnKSB8fCAoaWRfdHdvID4gJzYnKSkgewkJCQoJCQkvLyBzaWduYXR1cmUgZXJyb3IKCQkJdGhyb3cgRklfTVNHX0VSUk9SX01BR0lDX05VTUJFUjsKCQl9CgoJCS8vIFJlYWQgdGhlIGhlYWRlciBpbmZvcm1hdGlvbjogd2lkdGgsIGhlaWdodCBhbmQgdGhlICdtYXgnIHZhbHVlIGlmIGFueQoKCQlpbnQgd2lkdGggID0gR2V0SW50KGlvLCBoYW5kbGUpOwoJCWludCBoZWlnaHQgPSBHZXRJbnQoaW8sIGhhbmRsZSk7CgkJaW50IG1heHZhbCA9IDE7CgoJCWlmKChpZF90d28gPT0gJzInKSB8fCAoaWRfdHdvID09ICc1JykgfHwgKGlkX3R3byA9PSAnMycpIHx8IChpZF90d28gPT0gJzYnKSkgewoJCQltYXh2YWwgPSBHZXRJbnQoaW8sIGhhbmRsZSk7CgkJCWlmKChtYXh2YWwgPD0gMCkgfHwgKG1heHZhbCA+IDY1NTM1KSkgewoJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCAiSW52YWxpZCBtYXggdmFsdWUgOiAlZCIsIG1heHZhbCk7CgkJCQl0aHJvdyAoY29uc3QgY2hhciopTlVMTDsKCQkJfQoJCX0KCgkJLy8gQ3JlYXRlIGEgbmV3IERJQgoKCQlzd2l0Y2ggKGlkX3R3bykgewoJCQljYXNlICcxJzoKCQkJY2FzZSAnNCc6CgkJCQkvLyAxLWJpdAoJCQkJZGliID0gRnJlZUltYWdlX0FsbG9jYXRlSGVhZGVyKGhlYWRlcl9vbmx5LCB3aWR0aCwgaGVpZ2h0LCAxKTsKCQkJCWJyZWFrOwoKCQkJY2FzZSAnMic6CgkJCWNhc2UgJzUnOgoJCQkJaWYobWF4dmFsID4gMjU1KSB7CgkJCQkJLy8gMTYtYml0IGdyZXlzY2FsZQoJCQkJCWltYWdlX3R5cGUgPSBGSVRfVUlOVDE2OwoJCQkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZUhlYWRlclQoaGVhZGVyX29ubHksIGltYWdlX3R5cGUsIHdpZHRoLCBoZWlnaHQpOwoJCQkJfSBlbHNlIHsKCQkJCQkvLyA4LWJpdCBncmV5c2NhbGUKCQkJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGVIZWFkZXIoaGVhZGVyX29ubHksIHdpZHRoLCBoZWlnaHQsIDgpOwoJCQkJfQoJCQkJYnJlYWs7CgoJCQljYXNlICczJzoKCQkJY2FzZSAnNic6CgkJCQlpZihtYXh2YWwgPiAyNTUpIHsKCQkJCQkvLyA0OC1iaXQgUkdCCgkJCQkJaW1hZ2VfdHlwZSA9IEZJVF9SR0IxNjsKCQkJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGVIZWFkZXJUKGhlYWRlcl9vbmx5LCBpbWFnZV90eXBlLCB3aWR0aCwgaGVpZ2h0KTsKCQkJCX0gZWxzZSB7CgkJCQkJLy8gMjQtYml0IFJHQgoJCQkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZUhlYWRlcihoZWFkZXJfb25seSwgd2lkdGgsIGhlaWdodCwgMjQsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJCQkJfQoJCQkJYnJlYWs7CgkJfQoKCQlpZiAoZGliID09IE5VTEwpIHsKCQkJdGhyb3cgRklfTVNHX0VSUk9SX0RJQl9NRU1PUlk7CgkJfQoKCQkvLyBCdWlsZCBhIGdyZXlzY2FsZSBwYWxldHRlIGlmIG5lZWRlZAoKCQlpZihpbWFnZV90eXBlID09IEZJVF9CSVRNQVApIHsKCQkJc3dpdGNoKGlkX3R3bykgIHsKCQkJCWNhc2UgJzEnOgoJCQkJY2FzZSAnNCc6CgkJCQkJcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCQkJCQlwYWxbMF0ucmdiUmVkID0gcGFsWzBdLnJnYkdyZWVuID0gcGFsWzBdLnJnYkJsdWUgPSAwOwoJCQkJCXBhbFsxXS5yZ2JSZWQgPSBwYWxbMV0ucmdiR3JlZW4gPSBwYWxbMV0ucmdiQmx1ZSA9IDI1NTsKCQkJCQlicmVhazsKCgkJCQljYXNlICcyJzoKCQkJCWNhc2UgJzUnOgoJCQkJCXBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgkJCQkJZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CgkJCQkJCXBhbFtpXS5yZ2JSZWQJPQoJCQkJCQlwYWxbaV0ucmdiR3JlZW4gPQoJCQkJCQlwYWxbaV0ucmdiQmx1ZQk9IChCWVRFKWk7CgkJCQkJfQoJCQkJCWJyZWFrOwoKCQkJCWRlZmF1bHQ6CgkJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCWlmKGhlYWRlcl9vbmx5KSB7CgkJCS8vIGhlYWRlciBvbmx5IG1vZGUKCQkJcmV0dXJuIGRpYjsKCQl9CgoJCS8vIFJlYWQgdGhlIGltYWdlLi4uCgoJCXN3aXRjaChpZF90d28pICB7CgkJCWNhc2UgJzEnOgoJCQljYXNlICc0JzoKCQkJCS8vIHdyaXRlIHRoZSBiaXRtYXAgZGF0YQoKCQkJCWlmIChpZF90d28gPT0gJzEnKSB7CS8vIEFTQ0lJIGJpdG1hcAoJCQkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewkJCgkJCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJCQlmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJaWYgKEdldEludChpbywgaGFuZGxlKSA9PSAwKQoJCQkJCQkJCWJpdHNbeCA+PiAzXSB8PSAoMHg4MCA+PiAoeCAmIDB4NykpOwoJCQkJCQkJZWxzZQoJCQkJCQkJCWJpdHNbeCA+PiAzXSAmPSAoMHhGRjdGID4+ICh4ICYgMHg3KSk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9ICBlbHNlIHsJCS8vIFJhdyBiaXRtYXAKCQkJCQlpbnQgbGluZSA9IENhbGN1bGF0ZUxpbmUod2lkdGgsIDEpOwoKCQkJCQlmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsJCgkJCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJCQlmb3IgKHggPSAwOyB4IDwgbGluZTsgeCsrKSB7CgkJCQkJCQlpby0+cmVhZF9wcm9jKCZiaXRzW3hdLCAxLCAxLCBoYW5kbGUpOwoKCQkJCQkJCWJpdHNbeF0gPSB+Yml0c1t4XTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gZGliOwoKCQkJY2FzZSAnMic6CgkJCWNhc2UgJzUnOgoJCQkJaWYoaW1hZ2VfdHlwZSA9PSBGSVRfQklUTUFQKSB7CgkJCQkJLy8gd3JpdGUgdGhlIGJpdG1hcCBkYXRhCgoJCQkJCWlmKGlkX3R3byA9PSAnMicpIHsJCS8vIEFTQ0lJIGdyZXltYXAKCQkJCQkJaW50IGxldmVsID0gMDsKCgkJCQkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewkKCQkJCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCQlsZXZlbCA9IEdldEludChpbywgaGFuZGxlKTsKCQkJCQkJCQliaXRzW3hdID0gKEJZVEUpKCgyNTUgKiBsZXZlbCkgLyBtYXh2YWwpOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfSBlbHNlIHsJCS8vIFJhdyBncmV5bWFwCgkJCQkJCUJZVEUgbGV2ZWwgPSAwOwoKCQkJCQkJZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CQkKCQkJCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCQlpby0+cmVhZF9wcm9jKCZsZXZlbCwgMSwgMSwgaGFuZGxlKTsKCQkJCQkJCQliaXRzW3hdID0gKEJZVEUpKCgyNTUgKiAoaW50KWxldmVsKSAvIG1heHZhbCk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCQllbHNlIGlmKGltYWdlX3R5cGUgPT0gRklUX1VJTlQxNikgewoJCQkJCS8vIHdyaXRlIHRoZSBiaXRtYXAgZGF0YQoKCQkJCQlpZihpZF90d28gPT0gJzInKSB7CQkvLyBBU0NJSSBncmV5bWFwCgkJCQkJCWludCBsZXZlbCA9IDA7CgoJCQkJCQlmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsJCgkJCQkJCQlXT1JEICpiaXRzID0gKFdPUkQqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhlaWdodCAtIDEgLSB5KTsKCgkJCQkJCQlmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJCWxldmVsID0gR2V0SW50KGlvLCBoYW5kbGUpOwoJCQkJCQkJCWJpdHNbeF0gPSAoV09SRCkoKDY1NTM1ICogKGRvdWJsZSlsZXZlbCkgLyBtYXh2YWwpOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfSBlbHNlIHsJCS8vIFJhdyBncmV5bWFwCgkJCQkJCVdPUkQgbGV2ZWwgPSAwOwoKCQkJCQkJZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CQkKCQkJCQkJCVdPUkQgKmJpdHMgPSAoV09SRCopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSAtIHkpOwoKCQkJCQkJCWZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJbGV2ZWwgPSBSZWFkV29yZChpbywgaGFuZGxlKTsKCQkJCQkJCQliaXRzW3hdID0gKFdPUkQpKCg2NTUzNSAqIChkb3VibGUpbGV2ZWwpIC8gbWF4dmFsKTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gZGliOwoKCQkJY2FzZSAnMyc6CgkJCWNhc2UgJzYnOgoJCQkJaWYoaW1hZ2VfdHlwZSA9PSBGSVRfQklUTUFQKSB7CgkJCQkJLy8gd3JpdGUgdGhlIGJpdG1hcCBkYXRhCgoJCQkJCWlmIChpZF90d28gPT0gJzMnKSB7CQkvLyBBU0NJSSBwaXhtYXAKCQkJCQkJaW50IGxldmVsID0gMDsKCgkJCQkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewkKCQkJCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCQlsZXZlbCA9IEdldEludChpbywgaGFuZGxlKTsKCQkJCQkJCQliaXRzW0ZJX1JHQkFfUkVEXSA9IChCWVRFKSgoMjU1ICogbGV2ZWwpIC8gbWF4dmFsKTsJCS8vIFIKCQkJCQkJCQlsZXZlbCA9IEdldEludChpbywgaGFuZGxlKTsKCQkJCQkJCQliaXRzW0ZJX1JHQkFfR1JFRU5dID0gKEJZVEUpKCgyNTUgKiBsZXZlbCkgLyBtYXh2YWwpOwkvLyBHCgkJCQkJCQkJbGV2ZWwgPSBHZXRJbnQoaW8sIGhhbmRsZSk7CgkJCQkJCQkJYml0c1tGSV9SR0JBX0JMVUVdID0gKEJZVEUpKCgyNTUgKiBsZXZlbCkgLyBtYXh2YWwpOwkvLyBCCgoJCQkJCQkJCWJpdHMgKz0gMzsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0gIGVsc2UgewkJCS8vIFJhdyBwaXhtYXAKCQkJCQkJQllURSBsZXZlbCA9IDA7CgoJCQkJCQlmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsJCgkJCQkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSAtIHkpOwoKCQkJCQkJCWZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJaW8tPnJlYWRfcHJvYygmbGV2ZWwsIDEsIDEsIGhhbmRsZSk7IAoJCQkJCQkJCWJpdHNbRklfUkdCQV9SRURdID0gKEJZVEUpKCgyNTUgKiAoaW50KWxldmVsKSAvIG1heHZhbCk7CS8vIFIKCgkJCQkJCQkJaW8tPnJlYWRfcHJvYygmbGV2ZWwsIDEsIDEsIGhhbmRsZSk7CgkJCQkJCQkJYml0c1tGSV9SR0JBX0dSRUVOXSA9IChCWVRFKSgoMjU1ICogKGludClsZXZlbCkgLyBtYXh2YWwpOwkvLyBHCgoJCQkJCQkJCWlvLT5yZWFkX3Byb2MoJmxldmVsLCAxLCAxLCBoYW5kbGUpOwoJCQkJCQkJCWJpdHNbRklfUkdCQV9CTFVFXSA9IChCWVRFKSgoMjU1ICogKGludClsZXZlbCkgLyBtYXh2YWwpOwkvLyBCCgoJCQkJCQkJCWJpdHMgKz0gMzsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCWVsc2UgaWYoaW1hZ2VfdHlwZSA9PSBGSVRfUkdCMTYpIHsKCQkJCQkvLyB3cml0ZSB0aGUgYml0bWFwIGRhdGEKCgkJCQkJaWYgKGlkX3R3byA9PSAnMycpIHsJCS8vIEFTQ0lJIHBpeG1hcAoJCQkJCQlpbnQgbGV2ZWwgPSAwOwoKCQkJCQkJZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CQoJCQkJCQkJRklSR0IxNiAqYml0cyA9IChGSVJHQjE2KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCQlsZXZlbCA9IEdldEludChpbywgaGFuZGxlKTsKCQkJCQkJCQliaXRzW3hdLnJlZCA9IChXT1JEKSgoNjU1MzUgKiAoZG91YmxlKWxldmVsKSAvIG1heHZhbCk7CQkvLyBSCgkJCQkJCQkJbGV2ZWwgPSBHZXRJbnQoaW8sIGhhbmRsZSk7CgkJCQkJCQkJYml0c1t4XS5ncmVlbiA9IChXT1JEKSgoNjU1MzUgKiAoZG91YmxlKWxldmVsKSAvIG1heHZhbCk7CS8vIEcKCQkJCQkJCQlsZXZlbCA9IEdldEludChpbywgaGFuZGxlKTsKCQkJCQkJCQliaXRzW3hdLmJsdWUgPSAoV09SRCkoKDY1NTM1ICogKGRvdWJsZSlsZXZlbCkgLyBtYXh2YWwpOwkvLyBCCgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9ICBlbHNlIHsJCQkvLyBSYXcgcGl4bWFwCgkJCQkJCVdPUkQgbGV2ZWwgPSAwOwoKCQkJCQkJZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CQoJCQkJCQkJRklSR0IxNiAqYml0cyA9IChGSVJHQjE2KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCQlsZXZlbCA9IFJlYWRXb3JkKGlvLCBoYW5kbGUpOwoJCQkJCQkJCWJpdHNbeF0ucmVkID0gKFdPUkQpKCg2NTUzNSAqIChkb3VibGUpbGV2ZWwpIC8gbWF4dmFsKTsJCS8vIFIKCQkJCQkJCQlsZXZlbCA9IFJlYWRXb3JkKGlvLCBoYW5kbGUpOwoJCQkJCQkJCWJpdHNbeF0uZ3JlZW4gPSAoV09SRCkoKDY1NTM1ICogKGRvdWJsZSlsZXZlbCkgLyBtYXh2YWwpOwkvLyBHCgkJCQkJCQkJbGV2ZWwgPSBSZWFkV29yZChpbywgaGFuZGxlKTsKCQkJCQkJCQliaXRzW3hdLmJsdWUgPSAoV09SRCkoKDY1NTM1ICogKGRvdWJsZSlsZXZlbCkgLyBtYXh2YWwpOwkvLyBCCgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgoJCQkJcmV0dXJuIGRpYjsKCQl9CgoJfSBjYXRjaCAoY29uc3QgY2hhciAqdGV4dCkgIHsKCQlpZihkaWIpIEZyZWVJbWFnZV9VbmxvYWQoZGliKTsKCgkJaWYoTlVMTCAhPSB0ZXh0KSB7CgkJCXN3aXRjaChpZF90d28pICB7CgkJCQljYXNlICcxJzoKCQkJCWNhc2UgJzQnOgoJCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgdGV4dCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAnMic6CgkJCQljYXNlICc1JzoKCQkJCQlGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2Moc19mb3JtYXRfaWQsIHRleHQpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgJzMnOgoJCQkJY2FzZSAnNic6CgkJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCB0ZXh0KTsKCQkJCQlicmVhazsKCQkJfQoJCX0KCX0KCQkKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKU2F2ZShGcmVlSW1hZ2VJTyAqaW8sIEZJQklUTUFQICpkaWIsIGZpX2hhbmRsZSBoYW5kbGUsIGludCBwYWdlLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEpIHsKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCS8vICAgUE5NIFNhdmluZwoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJLy8KCS8vIE91dHB1dCBmb3JtYXQgOgoJLy8KCS8vIEJpdCBkZXB0aAkJZmxhZ3MJCQlmaWxlIGZvcm1hdAoJLy8gLS0tLS0tLS0tLS0tLSAgICAtLS0tLS0tLS0tLS0tLSAgLS0tLS0tLS0tLS0KCS8vIDEtYml0IC8gcGl4ZWwJUE5NX1NBVkVfQVNDSUkJUEJNIChQMSkKCS8vIDEtYml0IC8gcGl4ZWwJUE5NX1NBVkVfUkFXCVBCTSAoUDQpCgkvLyA4LWJpdCAvIHBpeGVsCVBOTV9TQVZFX0FTQ0lJCVBHTSAoUDIpCgkvLyA4LWJpdCAvIHBpeGVsCVBOTV9TQVZFX1JBVwlQR00gKFA1KQoJLy8gMjQtYml0IC8gcGl4ZWwJUE5NX1NBVkVfQVNDSUkJUFBNIChQMykKCS8vIDI0LWJpdCAvIHBpeGVsCVBOTV9TQVZFX1JBVwlQUE0gKFA2KQoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWludCB4LCB5OwoKCWNoYXIgYnVmZmVyWzI1Nl07CS8vIHRlbXBvcmFyeSBidWZmZXIgd2hvc2Ugc2l6ZSBzaG91bGQgYmUgZW5vdWdoIGZvciB3aGF0IHdlIG5lZWQKCglpZighZGliIHx8ICFoYW5kbGUpIHJldHVybiBGQUxTRTsKCQoJRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYik7CgoJaW50IGJwcAkJPSBGcmVlSW1hZ2VfR2V0QlBQKGRpYik7CglpbnQgd2lkdGgJPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCWludCBoZWlnaHQJPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7CgoJLy8gRmluZCB0aGUgYXBwcm9wcmlhdGUgbWFnaWMgbnVtYmVyIGZvciB0aGlzIGZpbGUgdHlwZQoKCWludCBtYWdpYyA9IDA7CglpbnQgbWF4dmFsID0gMjU1OwoKCXN3aXRjaChpbWFnZV90eXBlKSB7CgkJY2FzZSBGSVRfQklUTUFQOgoJCQlzd2l0Y2ggKGJwcCkgewoJCQkJY2FzZSAxIDoKCQkJCQltYWdpYyA9IDE7CS8vIFBCTSBmaWxlIChCICYgVykKCQkJCQlicmVhazsKCQkJCWNhc2UgOCA6IAkJCQoJCQkJCW1hZ2ljID0gMjsJLy8gUEdNIGZpbGUJKEdyZXlzY2FsZSkKCQkJCQlicmVhazsKCgkJCQljYXNlIDI0IDoKCQkJCQltYWdpYyA9IDM7CS8vIFBQTSBmaWxlIChSR0IpCgkJCQkJYnJlYWs7CgoJCQkJZGVmYXVsdDoKCQkJCQlyZXR1cm4gRkFMU0U7CS8vIEludmFsaWQgYml0IGRlcHRoCgkJCX0KCQkJYnJlYWs7CgkJCgkJY2FzZSBGSVRfVUlOVDE2OgoJCQltYWdpYyA9IDI7CS8vIFBHTSBmaWxlCShHcmV5c2NhbGUpCgkJCW1heHZhbCA9IDY1NTM1OwoJCQlicmVhazsKCgkJY2FzZSBGSVRfUkdCMTY6CgkJCW1hZ2ljID0gMzsJLy8gUFBNIGZpbGUgKFJHQikKCQkJbWF4dmFsID0gNjU1MzU7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlyZXR1cm4gRkFMU0U7Cgl9CgoKCWlmIChmbGFncyA9PSBQTk1fU0FWRV9SQVcpCgkJbWFnaWMgKz0gMzsKCgkvLyBXcml0ZSB0aGUgaGVhZGVyIGluZm8KCglzcHJpbnRmKGJ1ZmZlciwgIlAlZFxuJWQgJWRcbiIsIG1hZ2ljLCB3aWR0aCwgaGVpZ2h0KTsKCWlvLT53cml0ZV9wcm9jKCZidWZmZXIsICh1bnNpZ25lZCBpbnQpc3RybGVuKGJ1ZmZlciksIDEsIGhhbmRsZSk7CgoJaWYgKGJwcCAhPSAxKSB7CgkJc3ByaW50ZihidWZmZXIsICIlZFxuIiwgbWF4dmFsKTsKCQlpby0+d3JpdGVfcHJvYygmYnVmZmVyLCAodW5zaWduZWQgaW50KXN0cmxlbihidWZmZXIpLCAxLCBoYW5kbGUpOwoJfQoKCS8vIFdyaXRlIHRoZSBpbWFnZSBkYXRhCgkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKCWlmKGltYWdlX3R5cGUgPT0gRklUX0JJVE1BUCkgewoJCXN3aXRjaChicHApICB7CgkJCWNhc2UgMjQgOiAgICAgICAgICAgIC8vIDI0LWJpdCBSR0IsIDMgYnl0ZXMgcGVyIHBpeGVsCgkJCXsKCQkJCWlmIChmbGFncyA9PSBQTk1fU0FWRV9SQVcpICB7CgkJCQkJZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJCS8vIHdyaXRlIHRoZSBzY2FubGluZSB0byBkaXNjCgkJCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJCQlmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJaW8tPndyaXRlX3Byb2MoJmJpdHNbRklfUkdCQV9SRURdLCAxLCAxLCBoYW5kbGUpOwkvLyBSCgkJCQkJCQlpby0+d3JpdGVfcHJvYygmYml0c1tGSV9SR0JBX0dSRUVOXSwgMSwgMSwgaGFuZGxlKTsJLy8gRwoJCQkJCQkJaW8tPndyaXRlX3Byb2MoJmJpdHNbRklfUkdCQV9CTFVFXSwgMSwgMSwgaGFuZGxlKTsJLy8gQgoKCQkJCQkJCWJpdHMgKz0gMzsKCQkJCQkJfQoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJaW50IGxlbmd0aCA9IDA7CgoJCQkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkvLyB3cml0ZSB0aGUgc2NhbmxpbmUgdG8gZGlzYwoJCQkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSAtIHkpOwoJCQkJCQkKCQkJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCXNwcmludGYoYnVmZmVyLCAiJTNkICUzZCAlM2QgIiwgYml0c1tGSV9SR0JBX1JFRF0sIGJpdHNbRklfUkdCQV9HUkVFTl0sIGJpdHNbRklfUkdCQV9CTFVFXSk7CgoJCQkJCQkJaW8tPndyaXRlX3Byb2MoJmJ1ZmZlciwgKHVuc2lnbmVkIGludClzdHJsZW4oYnVmZmVyKSwgMSwgaGFuZGxlKTsKCgkJCQkJCQlsZW5ndGggKz0gMTI7CgoJCQkJCQkJaWYobGVuZ3RoID4gNTgpIHsKCQkJCQkJCQkvLyBObyBsaW5lIHNob3VsZCBiZSBsb25nZXIgdGhhbiA3MCBjaGFyYWN0ZXJzCgkJCQkJCQkJc3ByaW50ZihidWZmZXIsICJcbiIpOwoJCQkJCQkJCWlvLT53cml0ZV9wcm9jKCZidWZmZXIsICh1bnNpZ25lZCBpbnQpc3RybGVuKGJ1ZmZlciksIDEsIGhhbmRsZSk7CgkJCQkJCQkJbGVuZ3RoID0gMDsKCQkJCQkJCX0KCgkJCQkJCQliaXRzICs9IDM7CgkJCQkJCX0JCQkJCQoJCQkJCX0KCgkJCQl9CgkJCX0KCQkJYnJlYWs7CgoJCQljYXNlIDg6CQkvLyA4LWJpdCBncmV5c2NhbGUKCQkJewoJCQkJaWYgKGZsYWdzID09IFBOTV9TQVZFX1JBVykgIHsKCQkJCQlmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJLy8gd3JpdGUgdGhlIHNjYW5saW5lIHRvIGRpc2MKCQkJCQkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhlaWdodCAtIDEgLSB5KTsKCgkJCQkJCWZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQlpby0+d3JpdGVfcHJvYygmYml0c1t4XSwgMSwgMSwgaGFuZGxlKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJaW50IGxlbmd0aCA9IDA7CgoJCQkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkvLyB3cml0ZSB0aGUgc2NhbmxpbmUgdG8gZGlzYwoJCQkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSAtIHkpOwoKCQkJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCXNwcmludGYoYnVmZmVyLCAiJTNkICIsIGJpdHNbeF0pOwoKCQkJCQkJCWlvLT53cml0ZV9wcm9jKCZidWZmZXIsICh1bnNpZ25lZCBpbnQpc3RybGVuKGJ1ZmZlciksIDEsIGhhbmRsZSk7CgoJCQkJCQkJbGVuZ3RoICs9IDQ7CgoJCQkJCQkJaWYgKGxlbmd0aCA+IDY2KSB7CgkJCQkJCQkJLy8gTm8gbGluZSBzaG91bGQgYmUgbG9uZ2VyIHRoYW4gNzAgY2hhcmFjdGVycwoJCQkJCQkJCXNwcmludGYoYnVmZmVyLCAiXG4iKTsKCQkJCQkJCQlpby0+d3JpdGVfcHJvYygmYnVmZmVyLCAodW5zaWduZWQgaW50KXN0cmxlbihidWZmZXIpLCAxLCBoYW5kbGUpOwoJCQkJCQkJCWxlbmd0aCA9IDA7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQkJYnJlYWs7CgoJCQljYXNlIDE6CQkvLyAxLWJpdCBCICYgVwoJCQl7CgkJCQlpbnQgY29sb3I7CgoJCQkJaWYgKGZsYWdzID09IFBOTV9TQVZFX1JBVykgIHsKCQkJCQlmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkvLyB3cml0ZSB0aGUgc2NhbmxpbmUgdG8gZGlzYwoJCQkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSAtIHkpOwoKCQkJCQkJZm9yKHggPSAwOyB4IDwgKGludClGcmVlSW1hZ2VfR2V0TGluZShkaWIpOyB4KyspCgkJCQkJCQlpby0+d3JpdGVfcHJvYygmYml0c1t4XSwgMSwgMSwgaGFuZGxlKTsKCQkJCQl9CgkJCQl9IGVsc2UgIHsKCQkJCQlpbnQgbGVuZ3RoID0gMDsKCgkJCQkJZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJCS8vIHdyaXRlIHRoZSBzY2FubGluZSB0byBkaXNjCgkJCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJCQlmb3IgKHggPSAwOyB4IDwgKGludClGcmVlSW1hZ2VfR2V0TGluZShkaWIpICogODsgeCsrKQl7CgkJCQkJCQljb2xvciA9IChiaXRzW3g+PjNdICYgKDB4ODAgPj4gKHggJiAweDA3KSkpICE9IDA7CgoJCQkJCQkJc3ByaW50ZihidWZmZXIsICIlYyAiLCBjb2xvciA/ICcxJzonMCcpOwoKCQkJCQkJCWlvLT53cml0ZV9wcm9jKCZidWZmZXIsICh1bnNpZ25lZCBpbnQpc3RybGVuKGJ1ZmZlciksIDEsIGhhbmRsZSk7CgoJCQkJCQkJbGVuZ3RoICs9IDI7CgoJCQkJCQkJaWYgKGxlbmd0aCA+IDY4KSB7CgkJCQkJCQkJLy8gTm8gbGluZSBzaG91bGQgYmUgbG9uZ2VyIHRoYW4gNzAgY2hhcmFjdGVycwoJCQkJCQkJCXNwcmludGYoYnVmZmVyLCAiXG4iKTsKCQkJCQkJCQlpby0+d3JpdGVfcHJvYygmYnVmZmVyLCAodW5zaWduZWQgaW50KXN0cmxlbihidWZmZXIpLCAxLCBoYW5kbGUpOwoJCQkJCQkJCWxlbmd0aCA9IDA7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQkJCgkJCWJyZWFrOwoJCX0KCX0gLy8gaWYoRklUX0JJVE1BUCkKCgllbHNlIGlmKGltYWdlX3R5cGUgPT0gRklUX1VJTlQxNikgewkJLy8gMTYtYml0IGdyZXlzY2FsZQoJCWlmIChmbGFncyA9PSBQTk1fU0FWRV9SQVcpICB7CgkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJLy8gd3JpdGUgdGhlIHNjYW5saW5lIHRvIGRpc2MKCQkJCVdPUkQgKmJpdHMgPSAoV09SRCopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSAtIHkpOwoKCQkJCWZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJV3JpdGVXb3JkKGlvLCBoYW5kbGUsIGJpdHNbeF0pOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJaW50IGxlbmd0aCA9IDA7CgoJCQlmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCS8vIHdyaXRlIHRoZSBzY2FubGluZSB0byBkaXNjCgkJCQlXT1JEICpiaXRzID0gKFdPUkQqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhlaWdodCAtIDEgLSB5KTsKCgkJCQlmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCXNwcmludGYoYnVmZmVyLCAiJTVkICIsIGJpdHNbeF0pOwoKCQkJCQlpby0+d3JpdGVfcHJvYygmYnVmZmVyLCAodW5zaWduZWQgaW50KXN0cmxlbihidWZmZXIpLCAxLCBoYW5kbGUpOwoKCQkJCQlsZW5ndGggKz0gNjsKCgkJCQkJaWYgKGxlbmd0aCA+IDY0KSB7CgkJCQkJCS8vIE5vIGxpbmUgc2hvdWxkIGJlIGxvbmdlciB0aGFuIDcwIGNoYXJhY3RlcnMKCQkJCQkJc3ByaW50ZihidWZmZXIsICJcbiIpOwoJCQkJCQlpby0+d3JpdGVfcHJvYygmYnVmZmVyLCAodW5zaWduZWQgaW50KXN0cmxlbihidWZmZXIpLCAxLCBoYW5kbGUpOwoJCQkJCQlsZW5ndGggPSAwOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX0KCgllbHNlIGlmKGltYWdlX3R5cGUgPT0gRklUX1JHQjE2KSB7CQkvLyA0OC1iaXQgUkdCCgkJaWYgKGZsYWdzID09IFBOTV9TQVZFX1JBVykgIHsKCQkJZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkvLyB3cml0ZSB0aGUgc2NhbmxpbmUgdG8gZGlzYwoJCQkJRklSR0IxNiAqYml0cyA9IChGSVJHQjE2KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgoJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQlXcml0ZVdvcmQoaW8sIGhhbmRsZSwgYml0c1t4XS5yZWQpOwkJLy8gUgoJCQkJCVdyaXRlV29yZChpbywgaGFuZGxlLCBiaXRzW3hdLmdyZWVuKTsJLy8gRwoJCQkJCVdyaXRlV29yZChpbywgaGFuZGxlLCBiaXRzW3hdLmJsdWUpOwkvLyBCCgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQlpbnQgbGVuZ3RoID0gMDsKCgkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJLy8gd3JpdGUgdGhlIHNjYW5saW5lIHRvIGRpc2MKCQkJCUZJUkdCMTYgKmJpdHMgPSAoRklSR0IxNiopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSAtIHkpOwoJCQkJCgkJCQlmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCXNwcmludGYoYnVmZmVyLCAiJTVkICU1ZCAlNWQgIiwgYml0c1t4XS5yZWQsIGJpdHNbeF0uZ3JlZW4sIGJpdHNbeF0uYmx1ZSk7CgoJCQkJCWlvLT53cml0ZV9wcm9jKCZidWZmZXIsICh1bnNpZ25lZCBpbnQpc3RybGVuKGJ1ZmZlciksIDEsIGhhbmRsZSk7CgoJCQkJCWxlbmd0aCArPSAxODsKCgkJCQkJaWYobGVuZ3RoID4gNTIpIHsKCQkJCQkJLy8gTm8gbGluZSBzaG91bGQgYmUgbG9uZ2VyIHRoYW4gNzAgY2hhcmFjdGVycwoJCQkJCQlzcHJpbnRmKGJ1ZmZlciwgIlxuIik7CgkJCQkJCWlvLT53cml0ZV9wcm9jKCZidWZmZXIsICh1bnNpZ25lZCBpbnQpc3RybGVuKGJ1ZmZlciksIDEsIGhhbmRsZSk7CgkJCQkJCWxlbmd0aCA9IDA7CgkJCQkJfQoJCQkJfQkJCQkJCgkJCX0KCgkJfQoJfQoKCXJldHVybiBUUlVFOwp9CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vICAgSW5pdAovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cgp2b2lkIERMTF9DQUxMQ09OVgpJbml0UE5NKFBsdWdpbiAqcGx1Z2luLCBpbnQgZm9ybWF0X2lkKSB7CglzX2Zvcm1hdF9pZCA9IGZvcm1hdF9pZDsKCglwbHVnaW4tPmZvcm1hdF9wcm9jID0gRm9ybWF0OwoJcGx1Z2luLT5kZXNjcmlwdGlvbl9wcm9jID0gRGVzY3JpcHRpb247CglwbHVnaW4tPmV4dGVuc2lvbl9wcm9jID0gRXh0ZW5zaW9uOwoJcGx1Z2luLT5yZWdleHByX3Byb2MgPSBSZWdFeHByOwoJcGx1Z2luLT5vcGVuX3Byb2MgPSBOVUxMOwoJcGx1Z2luLT5jbG9zZV9wcm9jID0gTlVMTDsKCXBsdWdpbi0+cGFnZWNvdW50X3Byb2MgPSBOVUxMOwoJcGx1Z2luLT5wYWdlY2FwYWJpbGl0eV9wcm9jID0gTlVMTDsKCXBsdWdpbi0+bG9hZF9wcm9jID0gTG9hZDsKCXBsdWdpbi0+c2F2ZV9wcm9jID0gU2F2ZTsKCXBsdWdpbi0+dmFsaWRhdGVfcHJvYyA9IFZhbGlkYXRlOwoJcGx1Z2luLT5taW1lX3Byb2MgPSBNaW1lVHlwZTsKCXBsdWdpbi0+c3VwcG9ydHNfZXhwb3J0X2JwcF9wcm9jID0gU3VwcG9ydHNFeHBvcnREZXB0aDsKCXBsdWdpbi0+c3VwcG9ydHNfZXhwb3J0X3R5cGVfcHJvYyA9IFN1cHBvcnRzRXhwb3J0VHlwZTsKCXBsdWdpbi0+c3VwcG9ydHNfaWNjX3Byb2ZpbGVzX3Byb2MgPSBOVUxMOwoJcGx1Z2luLT5zdXBwb3J0c19ub19waXhlbHNfcHJvYyA9IFN1cHBvcnRzTm9QaXhlbHM7Cn0K