Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNTkcgLyBKTkcgaGVscGVycwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCi8qKgpSZWZlcmVuY2VzCmh0dHA6Ly93d3cubGlicG5nLm9yZy9wdWIvbW5nL3NwZWMvam5nLmh0bWwKaHR0cDovL3d3dy53My5vcmcvVFIvUE5HLwpodHRwOi8vbGlicG5nLm9yZy9wdWIvbW5nL3NwZWMvCiovCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKI2RlZmluZSBNTkdfSU5DTFVERV9KTkcKCiNpZmRlZiBNTkdfSU5DTFVERV9KTkcKI2RlZmluZSBNTkdfQ09MT1JUWVBFX0pQRUdHUkFZICAgICAgICAgICA4ICAgICAgIC8qIEpIRFIgKi8KI2RlZmluZSBNTkdfQ09MT1JUWVBFX0pQRUdDT0xPUiAgICAgICAgIDEwCiNkZWZpbmUgTU5HX0NPTE9SVFlQRV9KUEVHR1JBWUEgICAgICAgICAxMgojZGVmaW5lIE1OR19DT0xPUlRZUEVfSlBFR0NPTE9SQSAgICAgICAgMTQKCiNkZWZpbmUgTU5HX0JJVERFUFRIX0pQRUc4ICAgICAgICAgICAgICAgOCAgICAgICAvKiBKSERSICovCiNkZWZpbmUgTU5HX0JJVERFUFRIX0pQRUcxMiAgICAgICAgICAgICAxMgojZGVmaW5lIE1OR19CSVRERVBUSF9KUEVHOEFORDEyICAgICAgICAgMjAKCiNkZWZpbmUgTU5HX0NPTVBSRVNTSU9OX0JBU0VMSU5FSlBFRyAgICAgOCAgICAgICAvKiBKSERSICovCgojZGVmaW5lIE1OR19JTlRFUkxBQ0VfU0VRVUVOVElBTCAgICAgICAgIDAgICAgICAgLyogSkhEUiAqLwojZGVmaW5lIE1OR19JTlRFUkxBQ0VfUFJPR1JFU1NJVkUgICAgICAgIDgKI2VuZGlmIC8qIE1OR19JTkNMVURFX0pORyAqLwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNkZWZpbmUgSk5HX1NVUFBPUlRFRAoKLyoqIFNpemUgb2YgYSBKREFUIGNodW5rIG9uIHdyaXRpbmcgKi8KY29uc3QgRFdPUkQgSlBFR19DSFVOS19TSVpFCT0gODE5MjsKCi8qKiBQTkcgc2lnbmF0dXJlICovCnN0YXRpYyBjb25zdCBCWVRFIGdfcG5nX3NpZ25hdHVyZVs4XSA9IHsgMTM3LCA4MCwgNzgsIDcxLCAxMywgMTAsIDI2LCAxMCB9OwovKiogSk5HIHNpZ25hdHVyZSAqLwpzdGF0aWMgY29uc3QgQllURSBnX2puZ19zaWduYXR1cmVbOF0gPSB7IDEzOSwgNzQsIDc4LCA3MSwgMTMsIDEwLCAyNiwgMTAgfTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKiogQ2h1bmsgdHlwZSBjb252ZXJ0ZWQgdG8gZW51bSAqLwplbnVtIGVDaHVuY2tUeXBlIHsKCVVOS05PV05fQ0hVTkNLLAoJTUhEUiwKCUJBQ0ssCglCQVNJLAoJQ0xJUCwKCUNMT04sCglERUZJLAoJREhEUiwKCURJU0MsCglFTkRMLAoJRlJBTSwKCUlFTkQsCglJSERSLAoJSkhEUiwKCUxPT1AsCglNQUdOLAoJTUVORCwKCU1PVkUsCglQQVNULAoJUExURSwKCVNBVkUsCglTRUVLLAoJU0hPVywKCVRFUk0sCgliS0dELAoJY0hSTSwKCWdBTUEsCglpQ0NQLAoJbkVFRCwKCXBIWWcsCgl2cEFnLAoJcEhZcywKCXNCSVQsCglzUkdCLAoJdFJOUywKCUlEQVQsCglKREFULAoJSkRBQSwKCUpkQUEsCglKU0VQLAoJb0ZGcywKCWhJU1QsCglpVFh0LAoJc1BMVCwKCXNURVIsCgl0RVh0LAoJdElNRSwKCXpUWHQKfTsKCi8qKgpIZWxwZXIgZm9yIG1hcDxrZXksIHZhbHVlPiB3aGVyZSB2YWx1ZSBpcyBhIHBvaW50ZXIgdG8gYSBzdHJpbmcuIApVc2VkIHRvIHN0b3JlIHRFWHQgbWV0YWRhdGEuIAoqLwp0eXBlZGVmIHN0ZDo6bWFwPHN0ZDo6c3RyaW5nLCBzdGQ6OnN0cmluZz4gdEVYdE1BUDsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKgogIENvbnN0YW50IHN0cmluZ3MgZm9yIGtub3duIGNodW5rIHR5cGVzLiAgSWYgeW91IG5lZWQgdG8gYWRkIGEgY2h1bmssCiAgYWRkIGEgc3RyaW5nIGhvbGRpbmcgdGhlIG5hbWUgaGVyZS4gICBUbyBtYWtlIHRoZSBjb2RlIG1vcmUKICBwb3J0YWJsZSwgd2UgdXNlIEFTQ0lJIG51bWJlcnMgbGlrZSB0aGlzLCBub3QgY2hhcmFjdGVycy4KKi8KCnN0YXRpYyBCWVRFIG1uZ19NSERSWzVdPXsgNzcsICA3MiwgIDY4LCAgODIsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX0JBQ0tbNV09eyA2NiwgIDY1LCAgNjcsICA3NSwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfQkFTSVs1XT17IDY2LCAgNjUsICA4MywgIDczLCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19DTElQWzVdPXsgNjcsICA3NiwgIDczLCAgODAsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX0NMT05bNV09eyA2NywgIDc2LCAgNzksICA3OCwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfREVGSVs1XT17IDY4LCAgNjksICA3MCwgIDczLCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19ESERSWzVdPXsgNjgsICA3MiwgIDY4LCAgODIsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX0RJU0NbNV09eyA2OCwgIDczLCAgODMsICA2NywgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfRU5ETFs1XT17IDY5LCAgNzgsICA2OCwgIDc2LCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19GUkFNWzVdPXsgNzAsICA4MiwgIDY1LCAgNzcsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX0lFTkRbNV09eyA3MywgIDY5LCAgNzgsICA2OCwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfSUhEUls1XT17IDczLCAgNzIsICA2OCwgIDgyLCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19KSERSWzVdPXsgNzQsICA3MiwgIDY4LCAgODIsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX0xPT1BbNV09eyA3NiwgIDc5LCAgNzksICA4MCwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfTUFHTls1XT17IDc3LCAgNjUsICA3MSwgIDc4LCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19NRU5EWzVdPXsgNzcsICA2OSwgIDc4LCAgNjgsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX01PVkVbNV09eyA3NywgIDc5LCAgODYsICA2OSwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfUEFTVFs1XT17IDgwLCAgNjUsICA4MywgIDg0LCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19QTFRFWzVdPXsgODAsICA3NiwgIDg0LCAgNjksIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX1NBVkVbNV09eyA4MywgIDY1LCAgODYsICA2OSwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfU0VFS1s1XT17IDgzLCAgNjksICA2OSwgIDc1LCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19TSE9XWzVdPXsgODMsICA3MiwgIDc5LCAgODcsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX1RFUk1bNV09eyA4NCwgIDY5LCAgODIsICA3NywgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfYktHRFs1XT17IDk4LCAgNzUsICA3MSwgIDY4LCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19jSFJNWzVdPXsgOTksICA3MiwgIDgyLCAgNzcsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX2dBTUFbNV09ezEwMywgIDY1LCAgNzcsICA2NSwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfaUNDUFs1XT17MTA1LCAgNjcsICA2NywgIDgwLCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19uRUVEWzVdPXsxMTAsICA2OSwgIDY5LCAgNjgsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX3BIWWdbNV09ezExMiwgIDcyLCAgODksIDEwMywgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfdnBBZ1s1XT17MTE4LCAxMTIsICA2NSwgMTAzLCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19wSFlzWzVdPXsxMTIsICA3MiwgIDg5LCAxMTUsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX3NCSVRbNV09ezExNSwgIDY2LCAgNzMsICA4NCwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfc1JHQls1XT17MTE1LCAgODIsICA3MSwgIDY2LCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ190Uk5TWzVdPXsxMTYsICA4MiwgIDc4LCAgODMsIChCWVRFKSAnXDAnfTsKCiNpZiBkZWZpbmVkKEpOR19TVVBQT1JURUQpCnN0YXRpYyBCWVRFIG1uZ19JREFUWzVdPXsgNzMsICA2OCwgIDY1LCAgODQsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX0pEQVRbNV09eyA3NCwgIDY4LCAgNjUsICA4NCwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfSkRBQVs1XT17IDc0LCAgNjgsICA2NSwgIDY1LCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19KZEFBWzVdPXsgNzQsIDEwMCwgIDY1LCAgNjUsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX0pTRVBbNV09eyA3NCwgIDgzLCAgNjksICA4MCwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfb0ZGc1s1XT17MTExLCAgNzAsICA3MCwgMTE1LCAoQllURSkgJ1wwJ307CiNlbmRpZgoKc3RhdGljIEJZVEUgbW5nX2hJU1RbNV09ezEwNCwgIDczLCAgODMsICA4NCwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfaVRYdFs1XT17MTA1LCAgODQsICA4OCwgMTE2LCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ19zUExUWzVdPXsxMTUsICA4MCwgIDc2LCAgODQsIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX3NURVJbNV09ezExNSwgIDg0LCAgNjksICA4MiwgKEJZVEUpICdcMCd9OwpzdGF0aWMgQllURSBtbmdfdEVYdFs1XT17MTE2LCAgNjksICA4OCwgMTE2LCAoQllURSkgJ1wwJ307CnN0YXRpYyBCWVRFIG1uZ190SU1FWzVdPXsxMTYsICA3MywgIDc3LCAgNjksIChCWVRFKSAnXDAnfTsKc3RhdGljIEJZVEUgbW5nX3pUWHRbNV09ezEyMiwgIDg0LCAgODgsIDExNiwgKEJZVEUpICdcMCd9OwoKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKQ29udmVydCBhIGNodW5rIG5hbWUgdG8gYSB1bmlxdWUgSUQKKi8Kc3RhdGljIGVDaHVuY2tUeXBlIAptbmdfR2V0Q2h1bmNrVHlwZShjb25zdCBCWVRFICptQ2h1bmtOYW1lKSB7CglpZihtZW1jbXAobUNodW5rTmFtZSwgbW5nX01IRFIsIDQpID09IDApIHsKCQlyZXR1cm4gTUhEUjsKCX0KCWlmKG1lbWNtcChtQ2h1bmtOYW1lLCBtbmdfTE9PUCwgNCkgPT0gMCkgewoJCXJldHVybiBMT09QOwoJfQoJaWYobWVtY21wKG1DaHVua05hbWUsIG1uZ19ERUZJLCA0KSA9PSAwKSB7CgkJcmV0dXJuIERFRkk7Cgl9CglpZihtZW1jbXAobUNodW5rTmFtZSwgbW5nX1BMVEUsIDQpID09IDApIHsKCQlyZXR1cm4gUExURTsKCX0KCWlmKG1lbWNtcChtQ2h1bmtOYW1lLCBtbmdfdFJOUywgNCkgPT0gMCkgewoJCXJldHVybiB0Uk5TOwoJfQoJaWYobWVtY21wKG1DaHVua05hbWUsIG1uZ19JSERSLCA0KSA9PSAwKSB7CgkJcmV0dXJuIElIRFI7Cgl9CglpZihtZW1jbXAobUNodW5rTmFtZSwgbW5nX0pIRFIsIDQpID09IDApIHsKCQlyZXR1cm4gSkhEUjsKCX0KCWlmKG1lbWNtcChtQ2h1bmtOYW1lLCBtbmdfTUVORCwgNCkgPT0gMCkgewoJCXJldHVybiBNRU5EOwoJfQoJaWYobWVtY21wKG1DaHVua05hbWUsIG1uZ19JRU5ELCA0KSA9PSAwKSB7CgkJcmV0dXJuIElFTkQ7Cgl9CglpZihtZW1jbXAobUNodW5rTmFtZSwgbW5nX0pEQVQsIDQpID09IDApIHsKCQlyZXR1cm4gSkRBVDsKCX0KCWlmKG1lbWNtcChtQ2h1bmtOYW1lLCBtbmdfSURBVCwgNCkgPT0gMCkgewoJCXJldHVybiBJREFUOwoJfQoJaWYobWVtY21wKG1DaHVua05hbWUsIG1uZ19KREFBLCA0KSA9PSAwKSB7CgkJcmV0dXJuIEpEQUE7Cgl9CglpZihtZW1jbXAobUNodW5rTmFtZSwgbW5nX2dBTUEsIDQpID09IDApIHsKCQlyZXR1cm4gZ0FNQTsKCX0KCWlmKG1lbWNtcChtQ2h1bmtOYW1lLCBtbmdfcEhZcywgNCkgPT0gMCkgewoJCXJldHVybiBwSFlzOwoJfQoJaWYobWVtY21wKG1DaHVua05hbWUsIG1uZ19iS0dELCA0KSA9PSAwKSB7CgkJcmV0dXJuIGJLR0Q7Cgl9CglpZihtZW1jbXAobUNodW5rTmFtZSwgbW5nX3RFWHQsIDQpID09IDApIHsKCQlyZXR1cm4gdEVYdDsKCX0KCglyZXR1cm4gVU5LTk9XTl9DSFVOQ0s7Cn0KCmlubGluZSB2b2lkCm1uZ19Td2FwU2hvcnQoV09SRCAqc3ApIHsKI2lmbmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCglTd2FwU2hvcnQoc3ApOwojZW5kaWYKfQoKaW5saW5lIHZvaWQKbW5nX1N3YXBMb25nKERXT1JEICpscCkgewojaWZuZGVmIEZSRUVJTUFHRV9CSUdFTkRJQU4KCVN3YXBMb25nKGxwKTsKI2VuZGlmCn0KCi8qKgpSZXR1cm5zIHRoZSBzaXplLCBpbiBieXRlcywgb2YgYSBGcmVlSW1hZ2VJTyBzdHJlYW0sIGZyb20gdGhlIGN1cnJlbnQgcG9zaXRpb24uIAoqLwpzdGF0aWMgbG9uZwptbmdfTE9GKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSkgewoJbG9uZyBzdGFydF9wb3MgPSBpby0+dGVsbF9wcm9jKGhhbmRsZSk7Cglpby0+c2Vla19wcm9jKGhhbmRsZSwgMCwgU0VFS19FTkQpOwoJbG9uZyBmaWxlX2xlbmd0aCA9IGlvLT50ZWxsX3Byb2MoaGFuZGxlKTsKCWlvLT5zZWVrX3Byb2MoaGFuZGxlLCBzdGFydF9wb3MsIFNFRUtfU0VUKTsKCXJldHVybiBmaWxlX2xlbmd0aDsKfQoKLyoqCkNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gYSBQTkcgc3RyZWFtLCBmcm9tIElIRFIgdG8gSUVORC4gCklmIHN1Y2Nlc3NmdWwsIHRoZSBzdHJlYW0gcG9zaXRpb24sIGFzIGdpdmVuIGJ5IGlvLT50ZWxsX3Byb2MoaGFuZGxlKSwgCnNob3VsZCBiZSB0aGUgZW5kIG9mIHRoZSBQTkcgc3RyZWFtIGF0IHRoZSByZXR1cm4gb2YgdGhlIGZ1bmN0aW9uLiAKQHBhcmFtIGlvCkBwYXJhbSBoYW5kbGUKQHBhcmFtIGluUG9zCkBwYXJhbSBtX1RvdGFsQnl0ZXNPZkNodW5rcwpAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoqLwpzdGF0aWMgQk9PTCAKbW5nX0NvdW50UE5HQ2h1bmtzKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgbG9uZyBpblBvcywgdW5zaWduZWQgKm1fVG90YWxCeXRlc09mQ2h1bmtzKSB7Cglsb25nIG1MT0Y7Cglsb25nIG1Qb3M7CglCT09MIG1FbmQgPSBGQUxTRTsKCURXT1JEIG1MZW5ndGggPSAwOwoJQllURSBtQ2h1bmtOYW1lWzVdOwoKCSptX1RvdGFsQnl0ZXNPZkNodW5rcyA9IDA7CgoJLy8gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIGZpbGUKCW1MT0YgPSBtbmdfTE9GKGlvLCBoYW5kbGUpOwoKCS8vIGdvIHRvIHRoZSBzdGFydCBvZiB0aGUgZmlsZQoJaW8tPnNlZWtfcHJvYyhoYW5kbGUsIGluUG9zLCBTRUVLX1NFVCk7CgoJdHJ5IHsKCQkvLyBwYXJzZSBjaHVua3MKCQl3aGlsZShtRW5kID09IEZBTFNFKSB7CgkJCS8vIGNodW5rIGxlbmd0aAoJCQltUG9zID0gaW8tPnRlbGxfcHJvYyhoYW5kbGUpOwoJCQlpZihtUG9zICsgNCA+IG1MT0YpIHsKCQkJCXRocm93KDEpOwoJCQl9CgkJCWlvLT5yZWFkX3Byb2MoJm1MZW5ndGgsIDEsIDQsIGhhbmRsZSk7CgkJCW1uZ19Td2FwTG9uZygmbUxlbmd0aCk7CgkJCS8vIGNodW5rIG5hbWUKCQkJbVBvcyA9IGlvLT50ZWxsX3Byb2MoaGFuZGxlKTsKCQkJaWYobVBvcyArIDQgPiBtTE9GKSB7CgkJCQl0aHJvdygxKTsKCQkJfQoJCQlpby0+cmVhZF9wcm9jKCZtQ2h1bmtOYW1lWzBdLCAxLCA0LCBoYW5kbGUpOwoJCQltQ2h1bmtOYW1lWzRdID0gJ1wwJzsKCgkJCS8vIGdvIHRvIG5leHQgY2h1bmsKCQkJbVBvcyA9IGlvLT50ZWxsX3Byb2MoaGFuZGxlKTsKCQkJLy8gNCA9IHNpemUgb2YgdGhlIENSQwoJCQlpZihtUG9zICsgKGxvbmcpbUxlbmd0aCArIDQgPiBtTE9GKSB7CgkJCQl0aHJvdygxKTsKCQkJfQoJCQlpby0+c2Vla19wcm9jKGhhbmRsZSwgbUxlbmd0aCArIDQsIFNFRUtfQ1VSKTsKCgkJCXN3aXRjaCggbW5nX0dldENodW5ja1R5cGUobUNodW5rTmFtZSkgKSB7CgkJCQljYXNlIElIRFI6CgkJCQkJaWYobUxlbmd0aCAhPSAxMykgewoJCQkJCQl0aHJvdygxKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQkKCQkJCWNhc2UgSUVORDoKCQkJCQltRW5kID0gVFJVRTsJCQoJCQkJCS8vIHRoZSBsZW5ndGggYmVsb3cgaW5jbHVkZXMgNCBieXRlcyBDUkMsIGJ1dCBubyBieXRlcyBmb3IgTGVuZ3RoCgkJCQkJKm1fVG90YWxCeXRlc09mQ2h1bmtzID0gaW8tPnRlbGxfcHJvYyhoYW5kbGUpIC0gaW5Qb3M7CgkJCQkJYnJlYWs7CQkKCQkJCQoJCQkJY2FzZSBVTktOT1dOX0NIVU5DSzoKCQkJCWRlZmF1bHQ6CgkJCQkJYnJlYWs7CgkJCX0KCgkJfSAvLyB3aGlsZSghbUVuZCkKCgkJcmV0dXJuIFRSVUU7CgkJCgl9IGNhdGNoKGludCkgewoJCXJldHVybiBGQUxTRTsKCX0KfQoKLyoqClJldHJpZXZlIHRoZSBwb3NpdGlvbiBvZiBhIGNodW5rIGluIGEgUE5HIHN0cmVhbQpAcGFyYW0gaFBuZ01lbW9yeSBQTkcgc3RyZWFtIGhhbmRsZQpAcGFyYW0gY2h1bmtfbmFtZSBOYW1lIG9mIHRoZSBjaHVuayB0byBiZSBmb3VuZApAcGFyYW0gb2Zmc2V0IFN0YXJ0IG9mIHRoZSBzZWFyY2ggaW4gdGhlIHN0cmVhbQpAcGFyYW0gc3RhcnRfcG9zIFtyZXR1cm5lZCB2YWx1ZV0gU3RhcnQgcG9zaXRpb24gb2YgdGhlIGNodW5rCkBwYXJhbSBuZXh0X3BvcyBbcmV0dXJuZWQgdmFsdWVdIFN0YXJ0IHBvc2l0aW9uIG9mIHRoZSBuZXh0IGNodW5rCkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCiovCnN0YXRpYyBCT09MIAptbmdfRmluZENodW5rKEZJTUVNT1JZICpoUG5nTWVtb3J5LCBCWVRFICpjaHVua19uYW1lLCBsb25nIG9mZnNldCwgRFdPUkQgKnN0YXJ0X3BvcywgRFdPUkQgKm5leHRfcG9zKSB7CglEV09SRCBtTGVuZ3RoID0gMDsKCglCWVRFICpkYXRhID0gTlVMTDsKCURXT1JEIHNpemVfaW5fYnl0ZXMgPSAwOwoKCSpzdGFydF9wb3MgPSAwOwoJKm5leHRfcG9zID0gMDsKCgkvLyBnZXQgYSBwb2ludGVyIHRvIHRoZSBzdHJlYW0gYnVmZmVyCglGcmVlSW1hZ2VfQWNxdWlyZU1lbW9yeShoUG5nTWVtb3J5LCAmZGF0YSwgJnNpemVfaW5fYnl0ZXMpOwoJaWYoIShkYXRhICYmIHNpemVfaW5fYnl0ZXMpIHx8IChzaXplX2luX2J5dGVzIDwgMjApIHx8IChzaXplX2luX2J5dGVzIC0gb2Zmc2V0IDwgMjApKSB7CgkJLy8gbm90IGVub3VnaCBzcGFjZSB0byByZWFkIGEgc2lnbmF0dXJlKDggYnl0ZXMpICsgYSBjaHVuayhhdCBsZWFzdCAxMiBieXRlcykKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJdHJ5IHsKCQoJCS8vIHNraXAgdGhlIHNpZ25hdHVyZSBhbmQvb3IgYW55IGZvbGxvd2luZyBjaHVuayhzKQoJCURXT1JEIGNodW5rX3BvcyA9IG9mZnNldDsKCgkJd2hpbGUoMSkgewoJCQkvLyBnZXQgY2h1bmsgbGVuZ3RoCgkJCWlmKGNodW5rX3BvcyArIDQgPiBzaXplX2luX2J5dGVzKSB7CgkJCQlicmVhazsKCQkJfQoKCQkJbWVtY3B5KCZtTGVuZ3RoLCAmZGF0YVtjaHVua19wb3NdLCA0KTsKCQkJbW5nX1N3YXBMb25nKCZtTGVuZ3RoKTsKCQkJY2h1bmtfcG9zICs9IDQ7CgoJCQljb25zdCBEV09SRCBuZXh0X2NodW5rX3BvcyA9IGNodW5rX3BvcyArIDQgKyBtTGVuZ3RoICsgNDsKCQkJaWYobmV4dF9jaHVua19wb3MgPiBzaXplX2luX2J5dGVzKSB7CgkJCQlicmVhazsKCQkJfQoKCQkJLy8gZ2V0IGNodW5rIG5hbWUKCQkJaWYobWVtY21wKCZkYXRhW2NodW5rX3Bvc10sIGNodW5rX25hbWUsIDQpID09IDApIHsKCQkJCWNodW5rX3BvcyAtPSA0OwkvLyBmb3VuZCBjaHVuawoJCQkJKnN0YXJ0X3BvcyA9IGNodW5rX3BvczsKCQkJCSpuZXh0X3BvcyA9IG5leHRfY2h1bmtfcG9zOwoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQkJCgkJCWNodW5rX3BvcyA9IG5leHRfY2h1bmtfcG9zOwoJCX0KCgkJcmV0dXJuIEZBTFNFOwoKCX0gY2F0Y2goaW50KSB7CgkJcmV0dXJuIEZBTFNFOwoJfQp9CgovKioKUmVtb3ZlIGEgY2h1bmsgbG9jYXRlZCBhdCAoc3RhcnRfcG9zLCBuZXh0X3BvcykgaW4gdGhlIFBORyBzdHJlYW0KQHBhcmFtIGhQbmdNZW1vcnkgUE5HIHN0cmVhbSBoYW5kbGUKQHBhcmFtIHN0YXJ0X3BvcyBTdGFydCBwb3NpdGlvbiBvZiB0aGUgY2h1bmsKQHBhcmFtIG5leHRfcG9zIFN0YXJ0IHBvc2l0aW9uIG9mIHRoZSBuZXh0IGNodW5rCkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWxsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoqLwpzdGF0aWMgQk9PTCAKbW5nX0NvcHlSZW1vdmVDaHVua3MoRklNRU1PUlkgKmhQbmdNZW1vcnksIERXT1JEIHN0YXJ0X3BvcywgRFdPUkQgbmV4dF9wb3MpIHsKCUJZVEUgKmRhdGEgPSBOVUxMOwoJRFdPUkQgc2l6ZV9pbl9ieXRlcyA9IDA7CgoJLy8gbGVuZ3RoIG9mIHRoZSBjaHVuayB0byByZW1vdmUKCURXT1JEIGNodW5rX2xlbmd0aCA9IG5leHRfcG9zIC0gc3RhcnRfcG9zOwoJaWYoY2h1bmtfbGVuZ3RoID09IDApIHsKCQlyZXR1cm4gVFJVRTsKCX0KCgkvLyBnZXQgYSBwb2ludGVyIHRvIHRoZSBzdHJlYW0gYnVmZmVyCglGcmVlSW1hZ2VfQWNxdWlyZU1lbW9yeShoUG5nTWVtb3J5LCAmZGF0YSwgJnNpemVfaW5fYnl0ZXMpOwoJaWYoIShkYXRhICYmIHNpemVfaW5fYnl0ZXMpIHx8IChzaXplX2luX2J5dGVzIDwgMjApIHx8IChjaHVua19sZW5ndGggPj0gc2l6ZV9pbl9ieXRlcykpIHsKCQkvLyBub3QgZW5vdWdoIHNwYWNlIHRvIHJlYWQgYSBzaWduYXR1cmUoOCBieXRlcykgKyBhIGNodW5rKGF0IGxlYXN0IDEyIGJ5dGVzKQoJCXJldHVybiBGQUxTRTsKCX0KCQoJLy8gbmV3IGZpbGUgbGVuZ3RoCgl1bnNpZ25lZCBidWZmZXJfc2l6ZSA9IHNpemVfaW5fYnl0ZXMgKyBjaHVua19sZW5ndGg7CgoJQllURSAqYnVmZmVyID0gKEJZVEUqKW1hbGxvYyhidWZmZXJfc2l6ZSAqIHNpemVvZihCWVRFKSk7CglpZighYnVmZmVyKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoJbWVtY3B5KCZidWZmZXJbMF0sICZkYXRhWzBdLCBzdGFydF9wb3MpOwoJbWVtY3B5KCZidWZmZXJbc3RhcnRfcG9zXSwgJmRhdGFbbmV4dF9wb3NdLCBzaXplX2luX2J5dGVzIC0gbmV4dF9wb3MpOwoKCS8vIHNlZWsgdG8gdGhlIHN0YXJ0IG9mIHRoZSBzdHJlYW0KCUZyZWVJbWFnZV9TZWVrTWVtb3J5KGhQbmdNZW1vcnksIDAsIFNFRUtfU0VUKTsKCS8vIHJlLXdyaXRlIHRoZSBzdHJlYW0KCUZyZWVJbWFnZV9Xcml0ZU1lbW9yeShidWZmZXIsIDEsIGJ1ZmZlcl9zaXplLCBoUG5nTWVtb3J5KTsKCglmcmVlKGJ1ZmZlcik7CgoJcmV0dXJuIFRSVUU7Cn0KCi8qKgpJbnNlcnQgYSBjaHVuayBqdXN0IGJlZm9yZSB0aGUgaW5OZXh0Q2h1bmtOYW1lIGNodW5rCkBwYXJhbSBoUG5nTWVtb3J5IFBORyBzdHJlYW0gaGFuZGxlCkBwYXJhbSBzdGFydF9wb3MgU3RhcnQgcG9zaXRpb24gb2YgdGhlIGluTmV4dENodW5rTmFtZSBjaHVuawpAcGFyYW0gbmV4dF9wb3MgU3RhcnQgcG9zaXRpb24gb2YgdGhlIG5leHQgY2h1bmsKQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bGwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCiovCnN0YXRpYyBCT09MIAptbmdfQ29weUluc2VydENodW5rcyhGSU1FTU9SWSAqaFBuZ01lbW9yeSwgQllURSAqaW5OZXh0Q2h1bmtOYW1lLCBCWVRFICppbkluc2VydENodW5rLCBEV09SRCBpbkNodW5rTGVuZ3RoLCBEV09SRCBzdGFydF9wb3MsIERXT1JEIG5leHRfcG9zKSB7CglCWVRFICpkYXRhID0gTlVMTDsKCURXT1JEIHNpemVfaW5fYnl0ZXMgPSAwOwoKCS8vIGxlbmd0aCBvZiB0aGUgY2h1bmsgdG8gY2hlY2sKCURXT1JEIGNodW5rX2xlbmd0aCA9IG5leHRfcG9zIC0gc3RhcnRfcG9zOwoJaWYoY2h1bmtfbGVuZ3RoID09IDApIHsKCQlyZXR1cm4gVFJVRTsKCX0KCgkvLyBnZXQgYSBwb2ludGVyIHRvIHRoZSBzdHJlYW0gYnVmZmVyCglGcmVlSW1hZ2VfQWNxdWlyZU1lbW9yeShoUG5nTWVtb3J5LCAmZGF0YSwgJnNpemVfaW5fYnl0ZXMpOwoJaWYoIShkYXRhICYmIHNpemVfaW5fYnl0ZXMpIHx8IChzaXplX2luX2J5dGVzIDwgMjApIHx8IChjaHVua19sZW5ndGggPj0gc2l6ZV9pbl9ieXRlcykpIHsKCQkvLyBub3QgZW5vdWdoIHNwYWNlIHRvIHJlYWQgYSBzaWduYXR1cmUoOCBieXRlcykgKyBhIGNodW5rKGF0IGxlYXN0IDEyIGJ5dGVzKQoJCXJldHVybiBGQUxTRTsKCX0KCQoJLy8gbmV3IGZpbGUgbGVuZ3RoCgl1bnNpZ25lZCBidWZmZXJfc2l6ZSA9IGluQ2h1bmtMZW5ndGggKyBzaXplX2luX2J5dGVzOwoKCUJZVEUgKmJ1ZmZlciA9IChCWVRFKiltYWxsb2MoYnVmZmVyX3NpemUgKiBzaXplb2YoQllURSkpOwoJaWYoIWJ1ZmZlcikgewoJCXJldHVybiBGQUxTRTsKCX0KCXVuc2lnbmVkIHAgPSAwOwoJbWVtY3B5KCZidWZmZXJbcF0sICZkYXRhWzBdLCBzdGFydF9wb3MpOwoJcCArPSBzdGFydF9wb3M7CgltZW1jcHkoJmJ1ZmZlcltwXSwgaW5JbnNlcnRDaHVuaywgaW5DaHVua0xlbmd0aCk7CglwICs9IGluQ2h1bmtMZW5ndGg7CgltZW1jcHkoJmJ1ZmZlcltwXSwgJmRhdGFbc3RhcnRfcG9zXSwgc2l6ZV9pbl9ieXRlcyAtIHN0YXJ0X3Bvcyk7CgoJLy8gc2VlayB0byB0aGUgc3RhcnQgb2YgdGhlIHN0cmVhbQoJRnJlZUltYWdlX1NlZWtNZW1vcnkoaFBuZ01lbW9yeSwgMCwgU0VFS19TRVQpOwoJLy8gcmUtd3JpdGUgdGhlIHN0cmVhbQoJRnJlZUltYWdlX1dyaXRlTWVtb3J5KGJ1ZmZlciwgMSwgYnVmZmVyX3NpemUsIGhQbmdNZW1vcnkpOwoKCWZyZWUoYnVmZmVyKTsKCglyZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgCm1uZ19SZW1vdmVDaHVuayhGSU1FTU9SWSAqaFBuZ01lbW9yeSwgQllURSAqY2h1bmtfbmFtZSkgewoJQk9PTCBiUmVzdWx0ID0gRkFMU0U7CgoJRFdPUkQgc3RhcnRfcG9zID0gMDsKCURXT1JEIG5leHRfcG9zID0gMDsKCQoJYlJlc3VsdCA9IG1uZ19GaW5kQ2h1bmsoaFBuZ01lbW9yeSwgY2h1bmtfbmFtZSwgOCwgJnN0YXJ0X3BvcywgJm5leHRfcG9zKTsKCWlmKCFiUmVzdWx0KSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWJSZXN1bHQgPSBtbmdfQ29weVJlbW92ZUNodW5rcyhoUG5nTWVtb3J5LCBzdGFydF9wb3MsIG5leHRfcG9zKTsKCWlmKCFiUmVzdWx0KSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCAKbW5nX0luc2VydENodW5rKEZJTUVNT1JZICpoUG5nTWVtb3J5LCBCWVRFICppbk5leHRDaHVua05hbWUsIEJZVEUgKmluSW5zZXJ0Q2h1bmssIHVuc2lnbmVkIGNodW5rX2xlbmd0aCkgewoJQk9PTCBiUmVzdWx0ID0gRkFMU0U7CgoJRFdPUkQgc3RhcnRfcG9zID0gMDsKCURXT1JEIG5leHRfcG9zID0gMDsKCQoJYlJlc3VsdCA9IG1uZ19GaW5kQ2h1bmsoaFBuZ01lbW9yeSwgaW5OZXh0Q2h1bmtOYW1lLCA4LCAmc3RhcnRfcG9zLCAmbmV4dF9wb3MpOwoJaWYoIWJSZXN1bHQpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJYlJlc3VsdCA9IG1uZ19Db3B5SW5zZXJ0Q2h1bmtzKGhQbmdNZW1vcnksIGluTmV4dENodW5rTmFtZSwgaW5JbnNlcnRDaHVuaywgY2h1bmtfbGVuZ3RoLCBzdGFydF9wb3MsIG5leHRfcG9zKTsKCWlmKCFiUmVzdWx0KSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCXJldHVybiBUUlVFOwp9CgpzdGF0aWMgRklCSVRNQVAqIAptbmdfTG9hZEZyb21NZW1vcnlIYW5kbGUoRklNRU1PUlkgKmhtZW0sIGludCBmbGFncyA9IDApIHsKCWxvbmcgb2Zmc2V0ID0gMDsKCUZJQklUTUFQICpkaWIgPSBOVUxMOwoKCWlmKGhtZW0pIHsKCQkvLyBzZWVrIHRvIHRoZSBzdGFydCBvZiB0aGUgc3RyZWFtCgkJRnJlZUltYWdlX1NlZWtNZW1vcnkoaG1lbSwgb2Zmc2V0LCBTRUVLX1NFVCk7CgoJCS8vIGNoZWNrIHRoZSBmaWxlIHNpZ25hdHVyZSBhbmQgZGVkdWNlIGl0cyBmb3JtYXQKCQkvLyAodGhlIHNlY29uZCBhcmd1bWVudCBpcyBjdXJyZW50bHkgbm90IHVzZWQgYnkgRnJlZUltYWdlKQoJCUZSRUVfSU1BR0VfRk9STUFUIGZpZiA9IEZyZWVJbWFnZV9HZXRGaWxlVHlwZUZyb21NZW1vcnkoaG1lbSwgMCk7CgkJaWYoZmlmICE9IEZJRl9VTktOT1dOKSB7CgkJCWRpYiA9IEZyZWVJbWFnZV9Mb2FkRnJvbU1lbW9yeShmaWYsIGhtZW0sIGZsYWdzKTsKCQl9Cgl9CgkKCXJldHVybiBkaWI7Cn0KCi8qKgpXcml0ZSBhIGNodW5rIGluIGEgUE5HIHN0cmVhbSBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uLiAKQHBhcmFtIGNodW5rX25hbWUgTmFtZSBvZiB0aGUgY2h1bmsKQHBhcmFtIGNodW5rX2RhdGEgQ2h1bmsgYXJyYXkKQHBhcmFtIGxlbmd0aCBDaHVuayBsZW5ndGgKQHBhcmFtIGhQbmdNZW1vcnkgUE5HIHN0cmVhbSBoYW5kbGUKKi8Kc3RhdGljIHZvaWQKbW5nX1dyaXRlQ2h1bmsoQllURSAqY2h1bmtfbmFtZSwgQllURSAqY2h1bmtfZGF0YSwgRFdPUkQgbGVuZ3RoLCBGSU1FTU9SWSAqaFBuZ01lbW9yeSkgewoJRFdPUkQgY3JjX2ZpbGUgPSAwOwoJLy8gd3JpdGUgYSBQTkcgY2h1bmsgLi4uCgkvLyAtIGxlbmd0aAoJbW5nX1N3YXBMb25nKCZsZW5ndGgpOwoJRnJlZUltYWdlX1dyaXRlTWVtb3J5KCZsZW5ndGgsIDEsIDQsIGhQbmdNZW1vcnkpOwoJbW5nX1N3YXBMb25nKCZsZW5ndGgpOwoJLy8gLSBjaHVuayBuYW1lCglGcmVlSW1hZ2VfV3JpdGVNZW1vcnkoY2h1bmtfbmFtZSwgMSwgNCwgaFBuZ01lbW9yeSk7CglpZihjaHVua19kYXRhICYmIGxlbmd0aCkgewoJCS8vIC0gY2h1bmsgZGF0YQoJCUZyZWVJbWFnZV9Xcml0ZU1lbW9yeShjaHVua19kYXRhLCAxLCBsZW5ndGgsIGhQbmdNZW1vcnkpOwoJCS8vIC0gY3JjCgkJY3JjX2ZpbGUgPSBGcmVlSW1hZ2VfWkxpYkNSQzMyKDAsIGNodW5rX25hbWUsIDQpOwoJCWNyY19maWxlID0gRnJlZUltYWdlX1pMaWJDUkMzMihjcmNfZmlsZSwgY2h1bmtfZGF0YSwgbGVuZ3RoKTsKCQltbmdfU3dhcExvbmcoJmNyY19maWxlKTsKCQlGcmVlSW1hZ2VfV3JpdGVNZW1vcnkoJmNyY19maWxlLCAxLCA0LCBoUG5nTWVtb3J5KTsKCX0gZWxzZSB7CgkJLy8gLSBjcmMKCQljcmNfZmlsZSA9IEZyZWVJbWFnZV9aTGliQ1JDMzIoMCwgY2h1bmtfbmFtZSwgNCk7CgkJbW5nX1N3YXBMb25nKCZjcmNfZmlsZSk7CgkJRnJlZUltYWdlX1dyaXRlTWVtb3J5KCZjcmNfZmlsZSwgMSwgNCwgaFBuZ01lbW9yeSk7Cgl9Cgp9CgovKioKV3JhcCBhIElEQVQgY2h1bmsgYXMgYSBQTkcgc3RyZWFtLiAKVGhlIHN0cmVhbSBoYXMgdGhlIHN0cnVjdHVyZSB7IGdfcG5nX3NpZ25hdHVyZSwgSUhEUiwgSURBVCwgSUVORCB9ClRoZSBpbWFnZSBpcyBhc3N1bWVkIHRvIGJlIGEgZ3JleXNjYWxlIGltYWdlLiAKCkBwYXJhbSBqbmdfd2lkdGggSW1hZ2Ugd2lkdGgKQHBhcmFtIGpuZ19oZWlnaHQgSW1hZ2UgaGVpZ2h0CkBwYXJhbSBqbmdfYWxwaGFfc2FtcGxlX2RlcHRoIEJpdHMgcGVyIHBpeGVsCkBwYXJhbSBtQ2h1bmsgUE5HIGdyYXlzY2FsZSBJREFUIGZvcm1hdApAcGFyYW0gbUxlbmd0aCBJREFUIGNodW5rIGxlbmd0aApAcGFyYW0gaFBuZ01lbW9yeSBPdXRwdXQgbWVtb3J5IHN0cmVhbQoqLwpzdGF0aWMgdm9pZCAKbW5nX1dyaXRlUE5HU3RyZWFtKERXT1JEIGpuZ193aWR0aCwgRFdPUkQgam5nX2hlaWdodCwgQllURSBqbmdfYWxwaGFfc2FtcGxlX2RlcHRoLCBCWVRFICptQ2h1bmssIERXT1JEIG1MZW5ndGgsIEZJTUVNT1JZICpoUG5nTWVtb3J5KSB7CgkvLyBQTkcgZ3JheXNjYWxlIElEQVQgZm9ybWF0CgoJQllURSBkYXRhWzE0XTsKCgkvLyB3cmFwIHRoZSBJREFUIGNodW5rIGFzIGEgUE5HIHN0cmVhbQoKCS8vIHdyaXRlIFBORyBmaWxlIHNpZ25hdHVyZQoJRnJlZUltYWdlX1dyaXRlTWVtb3J5KGdfcG5nX3NpZ25hdHVyZSwgMSwgOCwgaFBuZ01lbW9yeSk7CgoJLy8gd3JpdGUgYSBJSERSIGNodW5rIC4uLgoJLyoKCVRoZSBJSERSIGNodW5rIG11c3QgYXBwZWFyIEZJUlNULiBJdCBjb250YWluczoKCVdpZHRoOiAgICAgICAgICAgICAgNCBieXRlcwoJSGVpZ2h0OiAgICAgICAgICAgICA0IGJ5dGVzCglCaXQgZGVwdGg6ICAgICAgICAgIDEgYnl0ZQoJQ29sb3IgdHlwZTogICAgICAgICAxIGJ5dGUKCUNvbXByZXNzaW9uIG1ldGhvZDogMSBieXRlCglGaWx0ZXIgbWV0aG9kOiAgICAgIDEgYnl0ZQoJSW50ZXJsYWNlIG1ldGhvZDogICAxIGJ5dGUKCSovCgkvLyAtIGNodW5rIGRhdGEKCW1uZ19Td2FwTG9uZygmam5nX3dpZHRoKTsKCW1uZ19Td2FwTG9uZygmam5nX2hlaWdodCk7CgltZW1jcHkoJmRhdGFbMF0sICZqbmdfd2lkdGgsIDQpOwoJbWVtY3B5KCZkYXRhWzRdLCAmam5nX2hlaWdodCwgNCk7CgltbmdfU3dhcExvbmcoJmpuZ193aWR0aCk7CgltbmdfU3dhcExvbmcoJmpuZ19oZWlnaHQpOwoJZGF0YVs4XSA9IGpuZ19hbHBoYV9zYW1wbGVfZGVwdGg7CglkYXRhWzldID0gMDsJLy8gY29sb3JfdHlwZSBncmF5IChqbmdfY29sb3JfdHlwZSkKCWRhdGFbMTBdID0gMDsJLy8gY29tcHJlc3Npb24gbWV0aG9kIDAgKGpuZ19hbHBoYV9jb21wcmVzc2lvbl9tZXRob2QpCglkYXRhWzExXSA9IDA7CS8vIGZpbHRlcl9tZXRob2QgMCAoam5nX2FscGhhX2ZpbHRlcl9tZXRob2QpCglkYXRhWzEyXSA9IDA7CS8vIGludGVybGFjZV9tZXRob2QgMCAoam5nX2FscGhhX2ludGVybGFjZV9tZXRob2QpCgoJbW5nX1dyaXRlQ2h1bmsobW5nX0lIRFIsICZkYXRhWzBdLCAxMywgaFBuZ01lbW9yeSk7CgoJLy8gd3JpdGUgYSBJREFUIGNodW5rIC4uLgoJbW5nX1dyaXRlQ2h1bmsobW5nX0lEQVQsIG1DaHVuaywgbUxlbmd0aCwgaFBuZ01lbW9yeSk7CgoJLy8gd3JpdGUgYSBJRU5EIGNodW5rIC4uLgoJbW5nX1dyaXRlQ2h1bmsobW5nX0lFTkQsIE5VTEwsIDAsIGhQbmdNZW1vcnkpOwoKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgpCdWlsZCBhbmQgc2V0IGEgRklUQUcgd2hvc2UgdHlwZSBpcyBGSURUX0FTQ0lJLiAKVGhlIHRhZyBtdXN0IGJlIGRlc3Ryb3llZCBieSB0aGUgY2FsbGVyIHVzaW5nIEZyZWVJbWFnZV9EZWxldGVUYWcuCkBwYXJhbSBtb2RlbCBNZXRhZGF0YSBtb2RlbCB0byBiZSBmaWxsZWQKQHBhcmFtIGRpYiBJbWFnZSB0byBiZSBmaWxsZWQKQHBhcmFtIGtleSBUYWcga2V5CkBwYXJhbSB2YWx1ZSBUYWcgdmFsdWUKQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKKi8Kc3RhdGljIEJPT0wgCm1uZ19TZXRLZXlWYWx1ZShGUkVFX0lNQUdFX01ETU9ERUwgbW9kZWwsIEZJQklUTUFQICpkaWIsIGNvbnN0IGNoYXIgKmtleSwgY29uc3QgY2hhciAqdmFsdWUpIHsKCWlmKCFkaWIgfHwgIWtleSB8fCAhdmFsdWUpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgkvLyBjcmVhdGUgYSB0YWcKCUZJVEFHICp0YWcgPSBGcmVlSW1hZ2VfQ3JlYXRlVGFnKCk7CglpZih0YWcpIHsKCQlCT09MIGJTdWNjZXNzID0gVFJVRTsKCQkvLyBmaWxsIHRoZSB0YWcKCQlEV09SRCB0YWdfbGVuZ3RoID0gKERXT1JEKShzdHJsZW4odmFsdWUpICsgMSk7CgkJYlN1Y2Nlc3MgJj0gRnJlZUltYWdlX1NldFRhZ0tleSh0YWcsIGtleSk7CgkJYlN1Y2Nlc3MgJj0gRnJlZUltYWdlX1NldFRhZ0xlbmd0aCh0YWcsIHRhZ19sZW5ndGgpOwoJCWJTdWNjZXNzICY9IEZyZWVJbWFnZV9TZXRUYWdDb3VudCh0YWcsIHRhZ19sZW5ndGgpOwoJCWJTdWNjZXNzICY9IEZyZWVJbWFnZV9TZXRUYWdUeXBlKHRhZywgRklEVF9BU0NJSSk7CgkJYlN1Y2Nlc3MgJj0gRnJlZUltYWdlX1NldFRhZ1ZhbHVlKHRhZywgdmFsdWUpOwoJCWlmKGJTdWNjZXNzKSB7CgkJCS8vIHNldCB0aGUgdGFnCgkJCUZyZWVJbWFnZV9TZXRNZXRhZGF0YShtb2RlbCwgZGliLCBGcmVlSW1hZ2VfR2V0VGFnS2V5KHRhZyksIHRhZyk7CgkJfQoJCUZyZWVJbWFnZV9EZWxldGVUYWcodGFnKTsKCQlyZXR1cm4gYlN1Y2Nlc3M7Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgovKioKUmVhZCBhIHRFWHQgY2h1bmsgYW5kIGV4dHJhY3QgdGhlIGtleS92YWx1ZSBwYWlyLiAKQHBhcmFtIGtleV92YWx1ZV9wYWlyIFtyZXR1cm5lZCB2YWx1ZV0gQXJyYXkgb2Yga2V5L3ZhbHVlIHBhaXJzCkBwYXJhbSBtQ2h1bmsgQ2h1bmsgZGF0YQpAcGFyYW0gbUxlbmd0aCBDaHVuayBsZW5ndGgKQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKKi8Kc3RhdGljIEJPT0wgCm1uZ19TZXRNZXRhZGF0YV90RVh0KHRFWHRNQVAgJmtleV92YWx1ZV9wYWlyLCBjb25zdCBCWVRFICptQ2h1bmssIERXT1JEIG1MZW5ndGgpIHsKCXN0ZDo6c3RyaW5nIGtleTsKCXN0ZDo6c3RyaW5nIHZhbHVlOwoJQllURSAqYnVmZmVyID0gKEJZVEUqKW1hbGxvYyhtTGVuZ3RoICogc2l6ZW9mKEJZVEUpKTsKCWlmKCFidWZmZXIpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CglEV09SRCBwb3MgPSAwOwoKCW1lbXNldChidWZmZXIsIDAsIG1MZW5ndGggKiBzaXplb2YoQllURSkpOwoKCWZvcihEV09SRCBpID0gMDsgaSA8IG1MZW5ndGg7IGkrKykgewoJCWJ1ZmZlcltwb3MrK10gPSBtQ2h1bmtbaV07CgkJaWYobUNodW5rW2ldID09ICdcMCcpIHsKCQkJaWYoa2V5LnNpemUoKSA9PSAwKSB7CgkJCQlrZXkgPSAoY2hhciopYnVmZmVyOwoJCQkJcG9zID0gMDsKCQkJCW1lbXNldChidWZmZXIsIDAsIG1MZW5ndGggKiBzaXplb2YoQllURSkpOwoJCQl9IGVsc2UgewoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9Cgl2YWx1ZSA9IChjaGFyKilidWZmZXI7CglmcmVlKGJ1ZmZlcik7CgoJa2V5X3ZhbHVlX3BhaXJba2V5XSA9IHZhbHVlOwoKCXJldHVybiBUUlVFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCkxvYWQgYSBGSUJJVE1BUCBmcm9tIGEgTU5HIG9yIGEgSk5HIHN0cmVhbQpAcGFyYW0gZm9ybWF0X2lkIElEIG9mIHRoZSBjYWxsZXIKQHBhcmFtIGlvIFN0cmVhbSBpL28gZnVuY3Rpb25zCkBwYXJhbSBoYW5kbGUgU3RyZWFtIGhhbmRsZQpAcGFyYW0gT2Zmc2V0IFN0YXJ0IG9mIHRoZSBmaXJzdCBjaHVuawpAcGFyYW0gZmxhZ3MgTG9hZGluZyBmbGFncwpAcmV0dXJuIFJldHVybnMgYSBkaWIgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBOVUxMIG90aGVyd2lzZQoqLwpGSUJJVE1BUCogCm1uZ19SZWFkQ2h1bmtzKGludCBmb3JtYXRfaWQsIEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgbG9uZyBPZmZzZXQsIGludCBmbGFncyA9IDApIHsKCURXT1JEIG1MZW5ndGggPSAwOwoJQllURSBtQ2h1bmtOYW1lWzVdOwoJQllURSAqbUNodW5rID0gTlVMTDsKCURXT1JEIGNyY19maWxlOwoJbG9uZyBMYXN0T2Zmc2V0OwoJbG9uZyBtT3JpZ1BvczsKCUJZVEUgKlBMVEVfZmlsZV9jaHVuayA9IE5VTEw7CS8vIHdob2xlIFBMVEUgY2h1bmsgKGxlbnRnaCwgbmFtZSwgYXJyYXksIGNyYykKCURXT1JEIFBMVEVfZmlsZV9zaXplID0gMDsJCS8vIHNpemUgb2YgUExURSBjaHVuawoKCUJPT0wgbV9IYXNHbG9iYWxQYWxldHRlID0gRkFMU0U7IC8vIG1heSB0dXJuIHRvIFRSVUUgaW4gUExURSBjaHVuawoJdW5zaWduZWQgbV9Ub3RhbEJ5dGVzT2ZDaHVua3MgPSAwOwoJRklCSVRNQVAgKmRpYiA9IE5VTEw7CglGSUJJVE1BUCAqZGliX2FscGhhID0gTlVMTDsKCglGSU1FTU9SWSAqaEpwZWdNZW1vcnkgPSBOVUxMOwoJRklNRU1PUlkgKmhQbmdNZW1vcnkgPSBOVUxMOwoJRklNRU1PUlkgKmhJREFUTWVtb3J5ID0gTlVMTDsKCgkvLyAtLS0KCURXT1JEIGpuZ193aWR0aCA9IDA7CglEV09SRCBqbmdfaGVpZ2h0ID0gMDsKCUJZVEUgam5nX2NvbG9yX3R5cGUgPSAwOwoJQllURSBqbmdfaW1hZ2Vfc2FtcGxlX2RlcHRoID0gMDsKCUJZVEUgam5nX2ltYWdlX2NvbXByZXNzaW9uX21ldGhvZCA9IDA7CgoJQllURSBqbmdfYWxwaGFfc2FtcGxlX2RlcHRoID0gMDsKCUJZVEUgam5nX2FscGhhX2NvbXByZXNzaW9uX21ldGhvZCA9IDA7CglCWVRFIGpuZ19hbHBoYV9maWx0ZXJfbWV0aG9kID0gMDsKCUJZVEUgam5nX2FscGhhX2ludGVybGFjZV9tZXRob2QgPSAwOwoKCURXT1JEIG1uZ19mcmFtZV93aWR0aCA9IDA7CglEV09SRCBtbmdfZnJhbWVfaGVpZ2h0ID0gMDsKCURXT1JEIG1uZ190aWNrc19wZXJfc2Vjb25kID0gMDsKCURXT1JEIG1uZ19ub21pbmFsX2xheWVyX2NvdW50ID0gMDsKCURXT1JEIG1uZ19ub21pbmFsX2ZyYW1lX2NvdW50ID0gMDsKCURXT1JEIG1uZ19ub21pbmFsX3BsYXlfdGltZSA9IDA7CglEV09SRCBtbmdfc2ltcGxpY2l0eV9wcm9maWxlID0gMDsKCgoJRFdPUkQgcmVzX3ggPSAyODM1OwkvLyA3MiBkcGkKCURXT1JEIHJlc195ID0gMjgzNTsJLy8gNzIgZHBpCglSR0JRVUFEIHJnYkJrQ29sb3IgPSB7MCwgMCwgMCwgMH07CglXT1JEIGJrX3JlZCwgYmtfZ3JlZW4sIGJrX2JsdWU7CglCT09MIGhhc0JrQ29sb3IgPSBGQUxTRTsKCUJPT0wgbUhhc0lEQVQgPSBGQUxTRTsKCgl0RVh0TUFQIGtleV92YWx1ZV9wYWlyOwoKCS8vIC0tLQoKCUJPT0wgaGVhZGVyX29ubHkgPSAoZmxhZ3MgJiBGSUZfTE9BRF9OT1BJWEVMUykgPT0gRklGX0xPQURfTk9QSVhFTFM7CgkKCS8vIGdldCB0aGUgZmlsZSBzaXplCgljb25zdCBsb25nIG1MT0YgPSBtbmdfTE9GKGlvLCBoYW5kbGUpOwoJLy8gZ28gdG8gdGhlIGZpcnN0IGNodW5rCglpby0+c2Vla19wcm9jKGhhbmRsZSwgT2Zmc2V0LCBTRUVLX1NFVCk7CgoJdHJ5IHsKCQlCT09MIG1FbmQgPSBGQUxTRTsKCgkJd2hpbGUobUVuZCA9PSBGQUxTRSkgewoJCQkvLyBzdGFydCBvZiB0aGUgY2h1bmsKCQkJTGFzdE9mZnNldCA9IGlvLT50ZWxsX3Byb2MoaGFuZGxlKTsKCQkJLy8gcmVhZCBsZW5ndGgKCQkJbUxlbmd0aCA9IDA7CQkJCgkJCWlvLT5yZWFkX3Byb2MoJm1MZW5ndGgsIDEsIHNpemVvZihtTGVuZ3RoKSwgaGFuZGxlKTsKCQkJbW5nX1N3YXBMb25nKCZtTGVuZ3RoKTsKCQkJLy8gcmVhZCBuYW1lCQkJCgkJCWlvLT5yZWFkX3Byb2MoJm1DaHVua05hbWVbMF0sIDEsIDQsIGhhbmRsZSk7CgkJCW1DaHVua05hbWVbNF0gPSAnXDAnOwoKCQkJaWYobUxlbmd0aCA+IDApIHsKCQkJCW1DaHVuayA9IChCWVRFKilyZWFsbG9jKG1DaHVuaywgbUxlbmd0aCk7CgkJCQlpZighbUNodW5rKSB7CgkJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKGZvcm1hdF9pZCwgIkVycm9yIHdoaWxlIHBhcnNpbmcgJXMgY2h1bms6IG91dCBvZiBtZW1vcnkiLCBtQ2h1bmtOYW1lKTsKCQkJCQl0aHJvdyAoY29uc3QgY2hhciopTlVMTDsKCQkJCX0JCQkJCgkJCQlPZmZzZXQgPSBpby0+dGVsbF9wcm9jKGhhbmRsZSk7CgkJCQlpZihPZmZzZXQgKyAobG9uZyltTGVuZ3RoID4gbUxPRikgewoJCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhmb3JtYXRfaWQsICJFcnJvciB3aGlsZSBwYXJzaW5nICVzIGNodW5rOiB1bmV4cGVjdGVkIGVuZCBvZiBmaWxlIiwgbUNodW5rTmFtZSk7CgkJCQkJdGhyb3cgKGNvbnN0IGNoYXIqKU5VTEw7CgkJCQl9CgkJCQkvLyByZWFkIGNodW5rCgkJCQlpby0+cmVhZF9wcm9jKG1DaHVuaywgMSwgbUxlbmd0aCwgaGFuZGxlKTsKCQkJfQoJCQkvLyByZWFkIGNyYwoJCQlpby0+cmVhZF9wcm9jKCZjcmNfZmlsZSwgMSwgc2l6ZW9mKGNyY19maWxlKSwgaGFuZGxlKTsKCQkJbW5nX1N3YXBMb25nKCZjcmNfZmlsZSk7CgkJCS8vIGNoZWNrIGNyYwoJCQlEV09SRCBjcmNfY2hlY2sgPSBGcmVlSW1hZ2VfWkxpYkNSQzMyKDAsICZtQ2h1bmtOYW1lWzBdLCA0KTsKCQkJY3JjX2NoZWNrID0gRnJlZUltYWdlX1pMaWJDUkMzMihjcmNfY2hlY2ssIG1DaHVuaywgbUxlbmd0aCk7CgkJCWlmKGNyY19jaGVjayAhPSBjcmNfZmlsZSkgewoJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKGZvcm1hdF9pZCwgIkVycm9yIHdoaWxlIHBhcnNpbmcgJXMgY2h1bms6IGJhZCBDUkMiLCBtQ2h1bmtOYW1lKTsKCQkJCXRocm93IChjb25zdCBjaGFyKilOVUxMOwoJCQl9CQkKCgkJCXN3aXRjaCggbW5nX0dldENodW5ja1R5cGUobUNodW5rTmFtZSkgKSB7CgkJCQljYXNlIE1IRFI6CgkJCQkJLy8gVGhlIE1IRFIgY2h1bmsgaXMgYWx3YXlzIGZpcnN0IGluIGFsbCBNTkcgZGF0YXN0cmVhbXMgZXhjZXB0IGZvciB0aG9zZSAKCQkJCQkvLyB0aGF0IGNvbnNpc3Qgb2YgYSBzaW5nbGUgUE5HIG9yIEpORyBkYXRhc3RyZWFtIHdpdGggYSBQTkcgb3IgSk5HIHNpZ25hdHVyZS4gCgkJCQkJaWYobUxlbmd0aCA9PSAyOCkgewoJCQkJCQltZW1jcHkoJm1uZ19mcmFtZV93aWR0aCwgJm1DaHVua1swXSwgNCk7CgkJCQkJCW1lbWNweSgmbW5nX2ZyYW1lX2hlaWdodCwgJm1DaHVua1s0XSwgNCk7CgkJCQkJCW1lbWNweSgmbW5nX3RpY2tzX3Blcl9zZWNvbmQsICZtQ2h1bmtbOF0sIDQpOwoJCQkJCQltZW1jcHkoJm1uZ19ub21pbmFsX2xheWVyX2NvdW50LCAmbUNodW5rWzEyXSwgNCk7CgkJCQkJCW1lbWNweSgmbW5nX25vbWluYWxfZnJhbWVfY291bnQsICZtQ2h1bmtbMTZdLCA0KTsKCQkJCQkJbWVtY3B5KCZtbmdfbm9taW5hbF9wbGF5X3RpbWUsICZtQ2h1bmtbMjBdLCA0KTsKCQkJCQkJbWVtY3B5KCZtbmdfc2ltcGxpY2l0eV9wcm9maWxlLCAmbUNodW5rWzI0XSwgNCk7CgoJCQkJCQltbmdfU3dhcExvbmcoJm1uZ19mcmFtZV93aWR0aCk7CgkJCQkJCW1uZ19Td2FwTG9uZygmbW5nX2ZyYW1lX2hlaWdodCk7CgkJCQkJCW1uZ19Td2FwTG9uZygmbW5nX3RpY2tzX3Blcl9zZWNvbmQpOwoJCQkJCQltbmdfU3dhcExvbmcoJm1uZ19ub21pbmFsX2xheWVyX2NvdW50KTsKCQkJCQkJbW5nX1N3YXBMb25nKCZtbmdfbm9taW5hbF9mcmFtZV9jb3VudCk7CgkJCQkJCW1uZ19Td2FwTG9uZygmbW5nX25vbWluYWxfcGxheV90aW1lKTsKCQkJCQkJbW5nX1N3YXBMb25nKCZtbmdfc2ltcGxpY2l0eV9wcm9maWxlKTsKCgkJCQkJfSBlbHNlIHsKCQkJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKGZvcm1hdF9pZCwgIkVycm9yIHdoaWxlIHBhcnNpbmcgJXMgY2h1bms6IHNpemUgaXMgJWQgaW5zdGVhZCBvZiAyOCIsIG1DaHVua05hbWUsIG1MZW5ndGgpOwoJCQkJCX0KCQkJCQlicmVhazsKCgkJCQljYXNlIE1FTkQ6CgkJCQkJbUVuZCA9IFRSVUU7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBMT09QOgoJCQkJY2FzZSBFTkRMOgoJCQkJCWJyZWFrOwoJCQkJY2FzZSBERUZJOgoJCQkJCWJyZWFrOwoJCQkJY2FzZSBTQVZFOgoJCQkJY2FzZSBTRUVLOgoJCQkJY2FzZSBURVJNOgoJCQkJCWJyZWFrOwoJCQkJY2FzZSBCQUNLOgoJCQkJCWJyZWFrOwoKCQkJCQkvLyBHbG9iYWwgIlBMVEUiIGFuZCAidFJOUyIgKGlmIGFueSkuICBQTkcgIlBMVEUiIHdpbGwgYmUgb2YgMCBieXRlLCBhcyBpdCB1c2VzIGdsb2JhbCBkYXRhLgoJCQkJY2FzZSBQTFRFOgkvLyBHbG9iYWwKCQkJCQltX0hhc0dsb2JhbFBhbGV0dGUgPSBUUlVFOwoJCQkJCVBMVEVfZmlsZV9zaXplID0gbUxlbmd0aCArIDEyOyAvLyAobGVudGdoLCBuYW1lLCBhcnJheSwgY3JjKSA9ICg0LCA0LCBtTGVuZ3RoLCA0KQoJCQkJCVBMVEVfZmlsZV9jaHVuayA9IChCWVRFKilyZWFsbG9jKFBMVEVfZmlsZV9jaHVuaywgUExURV9maWxlX3NpemUpOwoJCQkJCWlmKCFQTFRFX2ZpbGVfY2h1bmspIHsKCQkJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKGZvcm1hdF9pZCwgIkVycm9yIHdoaWxlIHBhcnNpbmcgJXMgY2h1bms6IG91dCBvZiBtZW1vcnkiLCBtQ2h1bmtOYW1lKTsKCQkJCQkJdGhyb3cgKGNvbnN0IGNoYXIqKU5VTEw7CgkJCQkJfSBlbHNlIHsKCQkJCQkJbU9yaWdQb3MgPSBpby0+dGVsbF9wcm9jKGhhbmRsZSk7CgkJCQkJCS8vIHNlZWsgdG8gdGhlIHN0YXJ0IG9mIHRoZSBjaHVuawoJCQkJCQlpby0+c2Vla19wcm9jKGhhbmRsZSwgTGFzdE9mZnNldCwgU0VFS19TRVQpOwoJCQkJCQkvLyBsb2FkIHRoZSB3aG9sZSBjaHVuawoJCQkJCQlpby0+cmVhZF9wcm9jKFBMVEVfZmlsZV9jaHVuaywgMSwgUExURV9maWxlX3NpemUsIGhhbmRsZSk7CgkJCQkJCS8vIGdvIHRvIHRoZSBzdGFydCBvZiB0aGUgbmV4dCBjaHVuawoJCQkJCQlpby0+c2Vla19wcm9jKGhhbmRsZSwgbU9yaWdQb3MsIFNFRUtfU0VUKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSB0Uk5TOgkvLyBHbG9iYWwKCQkJCQlicmVhazsKCQkJCQkKCQkJCWNhc2UgSUhEUjoKCQkJCQlPZmZzZXQgPSBMYXN0T2Zmc2V0OwoJCQkJCS8vIHBhcnNlIHRoZSBQTkcgZmlsZSBhbmQgZ2V0IGl0cyBmaWxlIHNpemUKCQkJCQlpZihtbmdfQ291bnRQTkdDaHVua3MoaW8sIGhhbmRsZSwgT2Zmc2V0LCAmbV9Ub3RhbEJ5dGVzT2ZDaHVua3MpID09IEZBTFNFKSB7CgkJCQkJCS8vIHJlYWNoIGFuIHVuZXhwZWN0ZWQgZW5kIG9mIGZpbGUKCQkJCQkJbUVuZCA9IFRSVUU7CgkJCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhmb3JtYXRfaWQsICJFcnJvciB3aGlsZSBwYXJzaW5nICVzIGNodW5rOiB1bmV4cGVjdGVkIGVuZCBvZiBQTkcgZmlsZSIsIG1DaHVua05hbWUpOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQkJCgkJCQkJLy8gd3JhcCB0aGUgeyBJSERSLCAuLi4sIElFTkQgfSBjaHVua3MgYXMgYSBQTkcgc3RyZWFtCgkJCQkJaWYoaFBuZ01lbW9yeSA9PSBOVUxMKSB7CgkJCQkJCWhQbmdNZW1vcnkgPSBGcmVlSW1hZ2VfT3Blbk1lbW9yeSgpOwoJCQkJCX0KCgkJCQkJbU9yaWdQb3MgPSBpby0+dGVsbF9wcm9jKGhhbmRsZSk7CgoJCQkJCS8vIHdyaXRlIFBORyBmaWxlIHNpZ25hdHVyZQoJCQkJCUZyZWVJbWFnZV9TZWVrTWVtb3J5KGhQbmdNZW1vcnksIDAsIFNFRUtfU0VUKTsKCQkJCQlGcmVlSW1hZ2VfV3JpdGVNZW1vcnkoZ19wbmdfc2lnbmF0dXJlLCAxLCA4LCBoUG5nTWVtb3J5KTsKCgkJCQkJbUNodW5rID0gKEJZVEUqKXJlYWxsb2MobUNodW5rLCBtX1RvdGFsQnl0ZXNPZkNodW5rcyk7CgkJCQkJaWYoIW1DaHVuaykgewoJCQkJCQlGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2MoZm9ybWF0X2lkLCAiRXJyb3Igd2hpbGUgcGFyc2luZyAlcyBjaHVuazogb3V0IG9mIG1lbW9yeSIsIG1DaHVua05hbWUpOwoJCQkJCQl0aHJvdyAoY29uc3QgY2hhciopTlVMTDsKCQkJCQl9CgkJCQkJCgkJCQkJLy8gb24gY2FsbGluZyBDb3VudFBOR0NodW5rcyBlYXJsaWVyLCB3ZSB3ZXJlIGluIE9mZnNldCBwb3MsCgkJCQkJLy8gZ28gYmFjayB0aGVyZQoJCQkJCWlvLT5zZWVrX3Byb2MoaGFuZGxlLCBPZmZzZXQsIFNFRUtfU0VUKTsKCQkJCQlpby0+cmVhZF9wcm9jKG1DaHVuaywgMSwgbV9Ub3RhbEJ5dGVzT2ZDaHVua3MsIGhhbmRsZSk7CgkJCQkJLy8gUHV0IGJhY2sgdG8gb3JpZ2luYWwgcG9zCgkJCQkJaW8tPnNlZWtfcHJvYyhoYW5kbGUsIG1PcmlnUG9zLCBTRUVLX1NFVCk7CgkJCQkJLy8gd3JpdGUgdGhlIFBORyBjaHVua3MKCQkJCQlGcmVlSW1hZ2VfV3JpdGVNZW1vcnkobUNodW5rLCAxLCBtX1RvdGFsQnl0ZXNPZkNodW5rcywgaFBuZ01lbW9yeSk7CgoJCQkJCS8vIHBsdWcgaW4gZ2xvYmFsIFBMVEUgaWYgbG9jYWwgUExURSBleGlzdHMKCQkJCQlpZihtX0hhc0dsb2JhbFBhbGV0dGUpIHsKCQkJCQkJLy8gZW5zdXJlIHdlIHJlbW92ZSBzb21lIGxvY2FsIGNodW5rcywgc28gdGhhdCBnbG9iYWwKCQkJCQkJLy8gIlBMVEUiIGNhbiBiZSBpbnNlcnRlZCByaWdodCBiZWZvcmUgIklEQVQiLgoJCQkJCQltbmdfUmVtb3ZlQ2h1bmsoaFBuZ01lbW9yeSwgbW5nX1BMVEUpOwoJCQkJCQltbmdfUmVtb3ZlQ2h1bmsoaFBuZ01lbW9yeSwgbW5nX3RSTlMpOwoJCQkJCQltbmdfUmVtb3ZlQ2h1bmsoaFBuZ01lbW9yeSwgbW5nX2JLR0QpOwoJCQkJCQkvLyBpbnNlcnQgZ2xvYmFsICJQTFRFIiBjaHVuayBpbiBpdHMgZW50aXJldHkgYmVmb3JlICJJREFUIgoJCQkJCQltbmdfSW5zZXJ0Q2h1bmsoaFBuZ01lbW9yeSwgbW5nX0lEQVQsIFBMVEVfZmlsZV9jaHVuaywgUExURV9maWxlX3NpemUpOwoJCQkJCX0KCgkJCQkJaWYoZGliKSBGcmVlSW1hZ2VfVW5sb2FkKGRpYik7CgkJCQkJZGliID0gbW5nX0xvYWRGcm9tTWVtb3J5SGFuZGxlKGhQbmdNZW1vcnksIGZsYWdzKTsKCgkJCQkJLy8gc3RvcCBhZnRlciB0aGUgZmlyc3QgaW1hZ2UKCQkJCQltRW5kID0gVFJVRTsKCQkJCQlicmVhazsKCgkJCQljYXNlIEpIRFI6CgkJCQkJaWYobUxlbmd0aCA9PSAxNikgewoJCQkJCQltZW1jcHkoJmpuZ193aWR0aCwgJm1DaHVua1swXSwgNCk7CgkJCQkJCW1lbWNweSgmam5nX2hlaWdodCwgJm1DaHVua1s0XSwgNCk7CgkJCQkJCW1uZ19Td2FwTG9uZygmam5nX3dpZHRoKTsKCQkJCQkJbW5nX1N3YXBMb25nKCZqbmdfaGVpZ2h0KTsKCgkJCQkJCWpuZ19jb2xvcl90eXBlID0gbUNodW5rWzhdOwoJCQkJCQlqbmdfaW1hZ2Vfc2FtcGxlX2RlcHRoID0gbUNodW5rWzldOwoJCQkJCQlqbmdfaW1hZ2VfY29tcHJlc3Npb25fbWV0aG9kID0gbUNodW5rWzEwXTsKCQkJCQkJLy9CWVRFIGpuZ19pbWFnZV9pbnRlcmxhY2VfbWV0aG9kID0gbUNodW5rWzExXTsJLy8gZm9yIGRlYnVnIG9ubHkKCgkJCQkJCWpuZ19hbHBoYV9zYW1wbGVfZGVwdGggPSBtQ2h1bmtbMTJdOwoJCQkJCQlqbmdfYWxwaGFfY29tcHJlc3Npb25fbWV0aG9kID0gbUNodW5rWzEzXTsKCQkJCQkJam5nX2FscGhhX2ZpbHRlcl9tZXRob2QgPSBtQ2h1bmtbMTRdOwoJCQkJCQlqbmdfYWxwaGFfaW50ZXJsYWNlX21ldGhvZCA9IG1DaHVua1sxNV07CgkJCQkJfSBlbHNlIHsKCQkJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKGZvcm1hdF9pZCwgIkVycm9yIHdoaWxlIHBhcnNpbmcgJXMgY2h1bms6IGludmFsaWQgY2h1bmsgbGVuZ3RoIiwgbUNodW5rTmFtZSk7CgkJCQkJCXRocm93IChjb25zdCBjaGFyKilOVUxMOwoJCQkJCX0KCQkJCQlicmVhazsKCgkJCQljYXNlIEpEQVQ6CgkJCQkJaWYoaEpwZWdNZW1vcnkgPT0gTlVMTCkgewoJCQkJCQloSnBlZ01lbW9yeSA9IEZyZWVJbWFnZV9PcGVuTWVtb3J5KCk7CgkJCQkJfQoJCQkJCS8vIGFzIHRoZXJlIG1heSBiZSBzZXZlcmFsIEpEQVQgY2h1bmtzLCBjb25jYXRlbmF0ZSB0aGVtCgkJCQkJRnJlZUltYWdlX1dyaXRlTWVtb3J5KG1DaHVuaywgMSwgbUxlbmd0aCwgaEpwZWdNZW1vcnkpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgSURBVDoKCQkJCQlpZighaGVhZGVyX29ubHkgJiYgKGpuZ19hbHBoYV9jb21wcmVzc2lvbl9tZXRob2QgPT0gMCkpIHsKCQkJCQkJLy8gUE5HIGdyYXlzY2FsZSBJREFUIGZvcm1hdAoJCQkJCQlpZihoSURBVE1lbW9yeSA9PSBOVUxMKSB7CgkJCQkJCQloSURBVE1lbW9yeSA9IEZyZWVJbWFnZV9PcGVuTWVtb3J5KCk7CgkJCQkJCQltSGFzSURBVCA9IFRSVUU7CgkJCQkJCX0KCQkJCQkJLy8gYXMgdGhlcmUgbWF5IGJlIHNldmVyYWwgSURBVCBjaHVua3MsIGNvbmNhdGVuYXRlIHRoZW0KCQkJCQkJRnJlZUltYWdlX1dyaXRlTWVtb3J5KG1DaHVuaywgMSwgbUxlbmd0aCwgaElEQVRNZW1vcnkpOwoJCQkJCX0KCQkJCQlicmVhazsKCgkJCQljYXNlIElFTkQ6CgkJCQkJaWYoIWhKcGVnTWVtb3J5KSB7CgkJCQkJCW1FbmQgPSBUUlVFOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQkJLy8gbG9hZCB0aGUgSlBFRwoJCQkJCWlmKGRpYikgewoJCQkJCQlGcmVlSW1hZ2VfVW5sb2FkKGRpYik7CgkJCQkJfQoJCQkJCWRpYiA9IG1uZ19Mb2FkRnJvbU1lbW9yeUhhbmRsZShoSnBlZ01lbW9yeSwgZmxhZ3MpOwoKCQkJCQkvLyBsb2FkIHRoZSBQTkcgYWxwaGEgbGF5ZXIKCQkJCQlpZihtSGFzSURBVCkgewoJCQkJCQlCWVRFICpkYXRhID0gTlVMTDsKCQkJCQkJRFdPUkQgc2l6ZV9pbl9ieXRlcyA9IDA7CgoJCQkJCQkvLyBnZXQgYSBwb2ludGVyIHRvIHRoZSBJREFUIGJ1ZmZlcgoJCQkJCQlGcmVlSW1hZ2VfQWNxdWlyZU1lbW9yeShoSURBVE1lbW9yeSwgJmRhdGEsICZzaXplX2luX2J5dGVzKTsKCQkJCQkJaWYoZGF0YSAmJiBzaXplX2luX2J5dGVzKSB7CgkJCQkJCQkvLyB3cmFwIHRoZSBJREFUIGNodW5rIGFzIGEgUE5HIHN0cmVhbQoJCQkJCQkJaWYoaFBuZ01lbW9yeSA9PSBOVUxMKSB7CgkJCQkJCQkJaFBuZ01lbW9yeSA9IEZyZWVJbWFnZV9PcGVuTWVtb3J5KCk7CgkJCQkJCQl9CgkJCQkJCQltbmdfV3JpdGVQTkdTdHJlYW0oam5nX3dpZHRoLCBqbmdfaGVpZ2h0LCBqbmdfYWxwaGFfc2FtcGxlX2RlcHRoLCBkYXRhLCBzaXplX2luX2J5dGVzLCBoUG5nTWVtb3J5KTsKCQkJCQkJCS8vIGxvYWQgdGhlIFBORwoJCQkJCQkJaWYoZGliX2FscGhhKSB7CgkJCQkJCQkJRnJlZUltYWdlX1VubG9hZChkaWJfYWxwaGEpOwoJCQkJCQkJfQoJCQkJCQkJZGliX2FscGhhID0gbW5nX0xvYWRGcm9tTWVtb3J5SGFuZGxlKGhQbmdNZW1vcnksIGZsYWdzKTsKCQkJCQkJfQoJCQkJCX0KCQkJCQkvLyBzdG9wIHRoZSBwYXJzaW5nCgkJCQkJbUVuZCA9IFRSVUU7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBKREFBOgoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgZ0FNQToKCQkJCQlicmVhazsKCgkJCQljYXNlIHBIWXM6CgkJCQkJLy8gdW5pdCBpcyBwaXhlbHMgcGVyIG1ldGVyCgkJCQkJbWVtY3B5KCZyZXNfeCwgJm1DaHVua1swXSwgNCk7CgkJCQkJbW5nX1N3YXBMb25nKCZyZXNfeCk7CgkJCQkJbWVtY3B5KCZyZXNfeSwgJm1DaHVua1s0XSwgNCk7CgkJCQkJbW5nX1N3YXBMb25nKCZyZXNfeSk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBiS0dEOgoJCQkJCW1lbWNweSgmYmtfcmVkLCAmbUNodW5rWzBdLCAyKTsKCQkJCQltbmdfU3dhcFNob3J0KCZia19yZWQpOwoJCQkJCXJnYkJrQ29sb3IucmdiUmVkID0gKEJZVEUpYmtfcmVkOwoJCQkJCW1lbWNweSgmYmtfZ3JlZW4sICZtQ2h1bmtbMl0sIDIpOwoJCQkJCW1uZ19Td2FwU2hvcnQoJmJrX2dyZWVuKTsKCQkJCQlyZ2JCa0NvbG9yLnJnYkdyZWVuID0gKEJZVEUpYmtfZ3JlZW47CgkJCQkJbWVtY3B5KCZia19ibHVlLCAmbUNodW5rWzRdLCAyKTsKCQkJCQltbmdfU3dhcFNob3J0KCZia19ibHVlKTsKCQkJCQlyZ2JCa0NvbG9yLnJnYkJsdWUgPSAoQllURSlia19ibHVlOwoJCQkJCWhhc0JrQ29sb3IgPSBUUlVFOwoJCQkJCWJyZWFrOwoJCQkJCgkJCQljYXNlIHRFWHQ6CgkJCQkJbW5nX1NldE1ldGFkYXRhX3RFWHQoa2V5X3ZhbHVlX3BhaXIsIG1DaHVuaywgbUxlbmd0aCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSBVTktOT1dOX0NIVU5DSzoKCQkJCWRlZmF1bHQ6CgkJCQkJYnJlYWs7CgoKCQkJfSAvLyBzd2l0Y2goIEdldENodW5ja1R5cGUgKQoJCX0gLy8gd2hpbGUoIW1FbmQpCgoJCUZyZWVJbWFnZV9DbG9zZU1lbW9yeShoSnBlZ01lbW9yeSk7CgkJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhQbmdNZW1vcnkpOwoJCUZyZWVJbWFnZV9DbG9zZU1lbW9yeShoSURBVE1lbW9yeSk7CgkJZnJlZShtQ2h1bmspOwoJCWZyZWUoUExURV9maWxlX2NodW5rKTsKCgkJLy8gY29udmVydCB0byAzMi1iaXQgaWYgYSB0cmFuc3BhcmVudCBsYXllciBpcyBhdmFpbGFibGUKCQlpZighaGVhZGVyX29ubHkgJiYgZGliX2FscGhhKSB7CgkJCUZJQklUTUFQICpkc3QgPSBGcmVlSW1hZ2VfQ29udmVydFRvMzJCaXRzKGRpYik7CgkJCWlmKChGcmVlSW1hZ2VfR2V0QlBQKGRpYl9hbHBoYSkgPT0gOCkgJiYgKEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliX2FscGhhKSA9PSBGSVRfQklUTUFQKSkgewoJCQkJRnJlZUltYWdlX1NldENoYW5uZWwoZHN0LCBkaWJfYWxwaGEsIEZJQ0NfQUxQSEEpOwoJCQl9IGVsc2UgewoJCQkJRklCSVRNQVAgKmRzdF9hbHBoYSA9IEZyZWVJbWFnZV9Db252ZXJ0VG84Qml0cyhkaWJfYWxwaGEpOwoJCQkJRnJlZUltYWdlX1NldENoYW5uZWwoZHN0LCBkc3RfYWxwaGEsIEZJQ0NfQUxQSEEpOwoJCQkJRnJlZUltYWdlX1VubG9hZChkc3RfYWxwaGEpOwoJCQl9CQkJCgkJCUZyZWVJbWFnZV9VbmxvYWQoZGliKTsKCQkJZGliID0gZHN0OwoJCX0KCQlGcmVlSW1hZ2VfVW5sb2FkKGRpYl9hbHBoYSk7CgoJCWlmKGRpYikgewoJCQkvLyBzZXQgbWV0YWRhdGEKCQkJRnJlZUltYWdlX1NldERvdHNQZXJNZXRlclgoZGliLCByZXNfeCk7CgkJCUZyZWVJbWFnZV9TZXREb3RzUGVyTWV0ZXJZKGRpYiwgcmVzX3kpOwoJCQlpZihoYXNCa0NvbG9yKSB7CgkJCQlGcmVlSW1hZ2VfU2V0QmFja2dyb3VuZENvbG9yKGRpYiwgJnJnYkJrQ29sb3IpOwoJCQl9CgkJCWlmKGtleV92YWx1ZV9wYWlyLnNpemUoKSkgewoJCQkJZm9yKHRFWHRNQVA6Oml0ZXJhdG9yIGogPSBrZXlfdmFsdWVfcGFpci5iZWdpbigpOyBqICE9IGtleV92YWx1ZV9wYWlyLmVuZCgpOyBqKyspIHsKCQkJCQlzdGQ6OnN0cmluZyBrZXkgPSAoKmopLmZpcnN0OwoJCQkJCXN0ZDo6c3RyaW5nIHZhbHVlID0gKCpqKS5zZWNvbmQ7CgkJCQkJbW5nX1NldEtleVZhbHVlKEZJTURfQ09NTUVOVFMsIGRpYiwga2V5LmNfc3RyKCksIHZhbHVlLmNfc3RyKCkpOwoJCQkJfQoJCQl9CgkJfQoJCQkKCQlyZXR1cm4gZGliOwoKCX0gY2F0Y2goY29uc3QgY2hhciAqdGV4dCkgewoJCUZyZWVJbWFnZV9DbG9zZU1lbW9yeShoSnBlZ01lbW9yeSk7CgkJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhQbmdNZW1vcnkpOwoJCUZyZWVJbWFnZV9DbG9zZU1lbW9yeShoSURBVE1lbW9yeSk7CgkJZnJlZShtQ2h1bmspOwoJCWZyZWUoUExURV9maWxlX2NodW5rKTsKCQlGcmVlSW1hZ2VfVW5sb2FkKGRpYik7CgkJRnJlZUltYWdlX1VubG9hZChkaWJfYWxwaGEpOwoJCWlmKHRleHQpIHsKCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKGZvcm1hdF9pZCwgdGV4dCk7CgkJfQoJCXJldHVybiBOVUxMOwoJfQp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCldyaXRlIGEgRklCSVRNQVAgdG8gYSBKTkcgc3RyZWFtCkBwYXJhbSBmb3JtYXRfaWQgSUQgb2YgdGhlIGNhbGxlcgpAcGFyYW0gaW8gU3RyZWFtIGkvbyBmdW5jdGlvbnMKQHBhcmFtIGRpYiBJbWFnZSB0byBiZSBzYXZlZApAcGFyYW0gaGFuZGxlIFN0cmVhbSBoYW5kbGUKQHBhcmFtIGZsYWdzIFNhdmluZyBmbGFncwpAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoqLwpCT09MIAptbmdfV3JpdGVKTkcoaW50IGZvcm1hdF9pZCwgRnJlZUltYWdlSU8gKmlvLCBGSUJJVE1BUCAqZGliLCBmaV9oYW5kbGUgaGFuZGxlLCBpbnQgZmxhZ3MpIHsKCURXT1JEIGpuZ193aWR0aCA9IDA7CglEV09SRCBqbmdfaGVpZ2h0ID0gMDsKCUJZVEUgam5nX2NvbG9yX3R5cGUgPSAwOwoJQllURSBqbmdfaW1hZ2Vfc2FtcGxlX2RlcHRoID0gODsKCUJZVEUgam5nX2ltYWdlX2NvbXByZXNzaW9uX21ldGhvZCA9IDg7CS8vICA4OiBJU08tMTA5MTgtMSBIdWZmbWFuLWNvZGVkIGJhc2VsaW5lIEpQRUcuCglCWVRFIGpuZ19pbWFnZV9pbnRlcmxhY2VfbWV0aG9kID0gMDsKCglCWVRFIGpuZ19hbHBoYV9zYW1wbGVfZGVwdGggPSAwOwoJQllURSBqbmdfYWxwaGFfY29tcHJlc3Npb25fbWV0aG9kID0gMDsKCUJZVEUgam5nX2FscGhhX2ZpbHRlcl9tZXRob2QgPSAwOwoJQllURSBqbmdfYWxwaGFfaW50ZXJsYWNlX21ldGhvZCA9IDA7CgoJQllURSBidWZmZXJbMTZdOwoKCUZJTUVNT1JZICpoSm5nTWVtb3J5ID0gTlVMTDsKCUZJTUVNT1JZICpoSnBlZ01lbW9yeSA9IE5VTEw7CglGSU1FTU9SWSAqaFBuZ01lbW9yeSA9IE5VTEw7CgoJRklCSVRNQVAgKmRpYl9yZ2IgPSBOVUxMOwoJRklCSVRNQVAgKmRpYl9hbHBoYSA9IE5VTEw7CgoJaWYoIWRpYiB8fCAoRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpICE9IEZJVF9CSVRNQVApKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCXVuc2lnbmVkIGJwcCA9IEZyZWVJbWFnZV9HZXRCUFAoZGliKTsKCglzd2l0Y2goYnBwKSB7CgkJY2FzZSA4OgoJCQlpZihGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlKGRpYikgPT0gRklDX01JTklTQkxBQ0spIHsKCQkJCWRpYl9yZ2IgPSBkaWI7CgkJCQlqbmdfY29sb3JfdHlwZSA9IE1OR19DT0xPUlRZUEVfSlBFR0dSQVk7CgkJCX0gZWxzZSB7CgkJCQkvLyBKUEVHIHBsdWdpbiB3aWxsIGNvbnZlcnQgb3RoZXIgdHlwZXMgKEZJQ19NSU5JU1dISVRFLCBGSUNfUEFMRVRURSkgdG8gMjQtYml0IG9uIHRoZSBmbHkKCQkJCS8vZGliX3JnYiA9IEZyZWVJbWFnZV9Db252ZXJ0VG8yNEJpdHMoZGliKTsKCQkJCWRpYl9yZ2IgPSBkaWI7CgkJCQlqbmdfY29sb3JfdHlwZSA9IE1OR19DT0xPUlRZUEVfSlBFR0NPTE9SOwoKCQkJfQoJCQlicmVhazsKCQljYXNlIDI0OgoJCQlkaWJfcmdiID0gZGliOwoJCQlqbmdfY29sb3JfdHlwZSA9IE1OR19DT0xPUlRZUEVfSlBFR0NPTE9SOwoJCQlicmVhazsKCQljYXNlIDMyOgoJCQlkaWJfcmdiID0gRnJlZUltYWdlX0NvbnZlcnRUbzI0Qml0cyhkaWIpOwoJCQlqbmdfY29sb3JfdHlwZSA9IE1OR19DT0xPUlRZUEVfSlBFR0NPTE9SQTsKCQkJam5nX2FscGhhX3NhbXBsZV9kZXB0aCA9IDg7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCXJldHVybiBGQUxTRTsKCX0KCglqbmdfd2lkdGggPSAoRFdPUkQpRnJlZUltYWdlX0dldFdpZHRoKGRpYik7CglqbmdfaGVpZ2h0ID0gKERXT1JEKUZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKTsKCgl0cnkgewoJCWhKbmdNZW1vcnkgPSBGcmVlSW1hZ2VfT3Blbk1lbW9yeSgpOwoKCQkvLyAtLS0gd3JpdGUgSk5HIGZpbGUgc2lnbmF0dXJlIC0tLQoJCUZyZWVJbWFnZV9Xcml0ZU1lbW9yeShnX2puZ19zaWduYXR1cmUsIDEsIDgsIGhKbmdNZW1vcnkpOwoKCQkvLyAtLS0gd3JpdGUgYSBKSERSIGNodW5rIC0tLQoJCVN3YXBMb25nKCZqbmdfd2lkdGgpOwoJCVN3YXBMb25nKCZqbmdfaGVpZ2h0KTsKCQltZW1jcHkoJmJ1ZmZlclswXSwgJmpuZ193aWR0aCwgNCk7CgkJbWVtY3B5KCZidWZmZXJbNF0sICZqbmdfaGVpZ2h0LCA0KTsKCQlTd2FwTG9uZygmam5nX3dpZHRoKTsKCQlTd2FwTG9uZygmam5nX2hlaWdodCk7CgkJYnVmZmVyWzhdID0gam5nX2NvbG9yX3R5cGU7CgkJYnVmZmVyWzldID0gam5nX2ltYWdlX3NhbXBsZV9kZXB0aDsKCQlidWZmZXJbMTBdID0gam5nX2ltYWdlX2NvbXByZXNzaW9uX21ldGhvZDsKCQlidWZmZXJbMTFdID0gam5nX2ltYWdlX2ludGVybGFjZV9tZXRob2Q7CgkJYnVmZmVyWzEyXSA9IGpuZ19hbHBoYV9zYW1wbGVfZGVwdGg7CgkJYnVmZmVyWzEzXSA9IGpuZ19hbHBoYV9jb21wcmVzc2lvbl9tZXRob2Q7CgkJYnVmZmVyWzE0XSA9IGpuZ19hbHBoYV9maWx0ZXJfbWV0aG9kOwoJCWJ1ZmZlclsxNV0gPSBqbmdfYWxwaGFfaW50ZXJsYWNlX21ldGhvZDsKCQltbmdfV3JpdGVDaHVuayhtbmdfSkhEUiwgJmJ1ZmZlclswXSwgMTYsIGhKbmdNZW1vcnkpOwoKCQkvLyAtLS0gd3JpdGUgYSBzZXF1ZW5jZSBvZiBKREFUIGNodW5rcyAtLS0KCQloSnBlZ01lbW9yeSA9IEZyZWVJbWFnZV9PcGVuTWVtb3J5KCk7CgkJZmxhZ3MgfD0gSlBFR19CQVNFTElORTsKCQlpZighRnJlZUltYWdlX1NhdmVUb01lbW9yeShGSUZfSlBFRywgZGliX3JnYiwgaEpwZWdNZW1vcnksIGZsYWdzKSkgewoJCQl0aHJvdyAoY29uc3QgY2hhciopTlVMTDsKCQl9CgkJaWYoZGliX3JnYiAhPSBkaWIpIHsKCQkJRnJlZUltYWdlX1VubG9hZChkaWJfcmdiKTsKCQkJZGliX3JnYiA9IE5VTEw7CgkJfQoJCXsKCQkJQllURSAqanBlZ19kYXRhID0gTlVMTDsKCQkJRFdPUkQgc2l6ZV9pbl9ieXRlcyA9IDA7CgkJCQoJCQkvLyBnZXQgYSBwb2ludGVyIHRvIHRoZSBzdHJlYW0gYnVmZmVyCgkJCUZyZWVJbWFnZV9BY3F1aXJlTWVtb3J5KGhKcGVnTWVtb3J5LCAmanBlZ19kYXRhLCAmc2l6ZV9pbl9ieXRlcyk7CgkJCS8vIHdyaXRlIGNodW5rcwoJCQlmb3IoRFdPUkQgayA9IDA7IGsgPCBzaXplX2luX2J5dGVzOykgewoJCQkJRFdPUkQgYnl0ZXNfbGVmdCA9IHNpemVfaW5fYnl0ZXMgLSBrOwoJCQkJRFdPUkQgY2h1bmtfc2l6ZSA9IE1JTihKUEVHX0NIVU5LX1NJWkUsIGJ5dGVzX2xlZnQpOwoJCQkJbW5nX1dyaXRlQ2h1bmsobW5nX0pEQVQsICZqcGVnX2RhdGFba10sIGNodW5rX3NpemUsIGhKbmdNZW1vcnkpOwoJCQkJayArPSBjaHVua19zaXplOwoJCQl9CgkJfQoJCUZyZWVJbWFnZV9DbG9zZU1lbW9yeShoSnBlZ01lbW9yeSk7CgkJaEpwZWdNZW1vcnkgPSBOVUxMOwoKCQkvLyAtLS0gd3JpdGUgYWxwaGEgbGF5ZXIgYXMgYSBzZXF1ZW5jZSBvZiBJREFUIGNodW5rIC0tLQoJCWlmKChicHAgPT0gMzIpICYmIChqbmdfY29sb3JfdHlwZSA9PSBNTkdfQ09MT1JUWVBFX0pQRUdDT0xPUkEpKSB7CgkJCWRpYl9hbHBoYSA9IEZyZWVJbWFnZV9HZXRDaGFubmVsKGRpYiwgRklDQ19BTFBIQSk7CgoJCQloUG5nTWVtb3J5ID0gRnJlZUltYWdlX09wZW5NZW1vcnkoKTsKCQkJaWYoIUZyZWVJbWFnZV9TYXZlVG9NZW1vcnkoRklGX1BORywgZGliX2FscGhhLCBoUG5nTWVtb3J5LCBQTkdfREVGQVVMVCkpIHsKCQkJCXRocm93IChjb25zdCBjaGFyKilOVUxMOwoJCQl9CgkJCUZyZWVJbWFnZV9VbmxvYWQoZGliX2FscGhhKTsKCQkJZGliX2FscGhhID0gTlVMTDsKCQkJLy8gZ2V0IHRoZSBJREFUIGNodW5rCgkJCXsJCQoJCQkJQk9PTCBiUmVzdWx0ID0gRkFMU0U7CgkJCQlEV09SRCBzdGFydF9wb3MgPSAwOwoJCQkJRFdPUkQgbmV4dF9wb3MgPSAwOwoJCQkJbG9uZyBvZmZzZXQgPSA4OwoJCQkJCgkJCQlkbyB7CgkJCQkJLy8gZmluZCB0aGUgbmV4dCBJREFUIGNodW5rIGZyb20gJ29mZnNldCcgcG9zaXRpb24KCQkJCQliUmVzdWx0ID0gbW5nX0ZpbmRDaHVuayhoUG5nTWVtb3J5LCBtbmdfSURBVCwgb2Zmc2V0LCAmc3RhcnRfcG9zLCAmbmV4dF9wb3MpOwoJCQkJCWlmKCFiUmVzdWx0KSBicmVhazsKCQkJCQkKCQkJCQlCWVRFICpwbmdfZGF0YSA9IE5VTEw7CgkJCQkJRFdPUkQgc2l6ZV9pbl9ieXRlcyA9IDA7CgkJCQkJCgkJCQkJLy8gZ2V0IGEgcG9pbnRlciB0byB0aGUgc3RyZWFtIGJ1ZmZlcgoJCQkJCUZyZWVJbWFnZV9BY3F1aXJlTWVtb3J5KGhQbmdNZW1vcnksICZwbmdfZGF0YSwgJnNpemVfaW5fYnl0ZXMpOwoJCQkJCS8vIHdyaXRlIHRoZSBJREFUIGNodW5rCgkJCQkJbW5nX1dyaXRlQ2h1bmsobW5nX0lEQVQsICZwbmdfZGF0YVtzdGFydF9wb3MrOF0sIG5leHRfcG9zIC0gc3RhcnRfcG9zIC0gMTIsIGhKbmdNZW1vcnkpOwoKCQkJCQlvZmZzZXQgPSBuZXh0X3BvczsKCgkJCQl9IHdoaWxlKGJSZXN1bHQpOwoJCQl9CgoJCQlGcmVlSW1hZ2VfQ2xvc2VNZW1vcnkoaFBuZ01lbW9yeSk7CgkJCWhQbmdNZW1vcnkgPSBOVUxMOwoJCX0KCgkJLy8gLS0tIHdyaXRlIGEgSUVORCBjaHVuayAtLS0KCQltbmdfV3JpdGVDaHVuayhtbmdfSUVORCwgTlVMTCwgMCwgaEpuZ01lbW9yeSk7CgoJCS8vIHdyaXRlIHRoZSBKTkcgb24gb3V0cHV0IHN0cmVhbQoJCXsKCQkJQllURSAqam5nX2RhdGEgPSBOVUxMOwoJCQlEV09SRCBzaXplX2luX2J5dGVzID0gMDsKCQkJRnJlZUltYWdlX0FjcXVpcmVNZW1vcnkoaEpuZ01lbW9yeSwgJmpuZ19kYXRhLCAmc2l6ZV9pbl9ieXRlcyk7CgkJCWlvLT53cml0ZV9wcm9jKGpuZ19kYXRhLCAxLCBzaXplX2luX2J5dGVzLCBoYW5kbGUpOwkJCQoJCX0KCgkJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhKbmdNZW1vcnkpOwoJCUZyZWVJbWFnZV9DbG9zZU1lbW9yeShoSnBlZ01lbW9yeSk7CgkJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhQbmdNZW1vcnkpOwoKCQlyZXR1cm4gVFJVRTsKCgl9IGNhdGNoKGNvbnN0IGNoYXIgKnRleHQpIHsKCQlGcmVlSW1hZ2VfQ2xvc2VNZW1vcnkoaEpuZ01lbW9yeSk7CgkJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhKcGVnTWVtb3J5KTsKCQlGcmVlSW1hZ2VfQ2xvc2VNZW1vcnkoaFBuZ01lbW9yeSk7CgkJaWYoZGliX3JnYiAmJiAoZGliX3JnYiAhPSBkaWIpKSB7CgkJCUZyZWVJbWFnZV9VbmxvYWQoZGliX3JnYik7CgkJfQoJCUZyZWVJbWFnZV9VbmxvYWQoZGliX2FscGhhKTsKCQlpZih0ZXh0KSB7CgkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhmb3JtYXRfaWQsIHRleHQpOwoJCX0KCQlyZXR1cm4gRkFMU0U7Cgl9Cn0K