Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgY29udmVyc2lvbiByb3V0aW5lcwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gRmxvcmlzIHZhbiBkZW4gQmVyZyAoZmx2ZGJlcmdAd3hzLm5sKQovLyAtIERhbGUgTGFyc29uIChkbGFyc29uQG5vcnNlc29mdC5jb20pCi8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8gLSBKYW5pIEthamFsYSAoamFuaWtAcmVtZWR5LmZpKQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgaW50ZXJuYWwgY29udmVyc2lvbnMgWCB0byAyNCBiaXRzCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0TGluZTFUbzI0KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzLCBSR0JRVUFEICpwYWxldHRlKSB7Cglmb3IgKGludCBjb2xzID0gMDsgY29scyA8IHdpZHRoX2luX3BpeGVsczsgY29scysrKSB7CgkJQllURSBpbmRleCA9IChzb3VyY2VbY29scyA+PiAzXSAmICgweDgwID4+IChjb2xzICYgMHgwNykpKSAhPSAwID8gMSA6IDA7CgoJCXRhcmdldFtGSV9SR0JBX0JMVUVdID0gcGFsZXR0ZVtpbmRleF0ucmdiQmx1ZTsKCQl0YXJnZXRbRklfUkdCQV9HUkVFTl0gPSBwYWxldHRlW2luZGV4XS5yZ2JHcmVlbjsKCQl0YXJnZXRbRklfUkdCQV9SRURdID0gcGFsZXR0ZVtpbmRleF0ucmdiUmVkOwoKCQl0YXJnZXQgKz0gMzsKCX0KfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRMaW5lNFRvMjQoQllURSAqdGFyZ2V0LCBCWVRFICpzb3VyY2UsIGludCB3aWR0aF9pbl9waXhlbHMsIFJHQlFVQUQgKnBhbGV0dGUpIHsKCUJPT0wgbG93X25pYmJsZSA9IEZBTFNFOwoJaW50IHggPSAwOwoKCWZvciAoaW50IGNvbHMgPSAwOyBjb2xzIDwgd2lkdGhfaW5fcGl4ZWxzOyArK2NvbHMgKSB7CgkJaWYgKGxvd19uaWJibGUpIHsKCQkJdGFyZ2V0W0ZJX1JHQkFfQkxVRV0gPSBwYWxldHRlW0xPV05JQkJMRShzb3VyY2VbeF0pXS5yZ2JCbHVlOwoJCQl0YXJnZXRbRklfUkdCQV9HUkVFTl0gPSBwYWxldHRlW0xPV05JQkJMRShzb3VyY2VbeF0pXS5yZ2JHcmVlbjsKCQkJdGFyZ2V0W0ZJX1JHQkFfUkVEXSA9IHBhbGV0dGVbTE9XTklCQkxFKHNvdXJjZVt4XSldLnJnYlJlZDsKCgkJCXgrKzsKCQl9IGVsc2UgewoJCQl0YXJnZXRbRklfUkdCQV9CTFVFXSA9IHBhbGV0dGVbSElOSUJCTEUoc291cmNlW3hdKSA+PiA0XS5yZ2JCbHVlOwoJCQl0YXJnZXRbRklfUkdCQV9HUkVFTl0gPSBwYWxldHRlW0hJTklCQkxFKHNvdXJjZVt4XSkgPj4gNF0ucmdiR3JlZW47CgkJCXRhcmdldFtGSV9SR0JBX1JFRF0gPSBwYWxldHRlW0hJTklCQkxFKHNvdXJjZVt4XSkgPj4gNF0ucmdiUmVkOwoJCX0KCgkJbG93X25pYmJsZSA9ICFsb3dfbmliYmxlOwoKCQl0YXJnZXQgKz0gMzsKCX0KfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRMaW5lOFRvMjQoQllURSAqdGFyZ2V0LCBCWVRFICpzb3VyY2UsIGludCB3aWR0aF9pbl9waXhlbHMsIFJHQlFVQUQgKnBhbGV0dGUpIHsKCWZvciAoaW50IGNvbHMgPSAwOyBjb2xzIDwgd2lkdGhfaW5fcGl4ZWxzOyBjb2xzKyspIHsKCQl0YXJnZXRbRklfUkdCQV9CTFVFXSA9IHBhbGV0dGVbc291cmNlW2NvbHNdXS5yZ2JCbHVlOwoJCXRhcmdldFtGSV9SR0JBX0dSRUVOXSA9IHBhbGV0dGVbc291cmNlW2NvbHNdXS5yZ2JHcmVlbjsKCQl0YXJnZXRbRklfUkdCQV9SRURdID0gcGFsZXR0ZVtzb3VyY2VbY29sc11dLnJnYlJlZDsKCgkJdGFyZ2V0ICs9IDM7Cgl9Cn0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9Db252ZXJ0TGluZTE2VG8yNF81NTUoQllURSAqdGFyZ2V0LCBCWVRFICpzb3VyY2UsIGludCB3aWR0aF9pbl9waXhlbHMpIHsKCVdPUkQgKmJpdHMgPSAoV09SRCAqKXNvdXJjZTsKCglmb3IgKGludCBjb2xzID0gMDsgY29scyA8IHdpZHRoX2luX3BpeGVsczsgY29scysrKSB7CgkJdGFyZ2V0W0ZJX1JHQkFfUkVEXSAgID0gKEJZVEUpKCgoKGJpdHNbY29sc10gJiBGSTE2XzU1NV9SRURfTUFTSykgPj4gRkkxNl81NTVfUkVEX1NISUZUKSAqIDB4RkYpIC8gMHgxRik7CgkJdGFyZ2V0W0ZJX1JHQkFfR1JFRU5dID0gKEJZVEUpKCgoKGJpdHNbY29sc10gJiBGSTE2XzU1NV9HUkVFTl9NQVNLKSA+PiBGSTE2XzU1NV9HUkVFTl9TSElGVCkgKiAweEZGKSAvIDB4MUYpOwoJCXRhcmdldFtGSV9SR0JBX0JMVUVdICA9IChCWVRFKSgoKChiaXRzW2NvbHNdICYgRkkxNl81NTVfQkxVRV9NQVNLKSA+PiBGSTE2XzU1NV9CTFVFX1NISUZUKSAqIDB4RkYpIC8gMHgxRik7CgoJCXRhcmdldCArPSAzOwoJfQp9Cgp2b2lkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQ29udmVydExpbmUxNlRvMjRfNTY1KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzKSB7CglXT1JEICpiaXRzID0gKFdPUkQgKilzb3VyY2U7CgoJZm9yIChpbnQgY29scyA9IDA7IGNvbHMgPCB3aWR0aF9pbl9waXhlbHM7IGNvbHMrKykgewoJCXRhcmdldFtGSV9SR0JBX1JFRF0gICA9IChCWVRFKSgoKChiaXRzW2NvbHNdICYgRkkxNl81NjVfUkVEX01BU0spID4+IEZJMTZfNTY1X1JFRF9TSElGVCkgKiAweEZGKSAvIDB4MUYpOwoJCXRhcmdldFtGSV9SR0JBX0dSRUVOXSA9IChCWVRFKSgoKChiaXRzW2NvbHNdICYgRkkxNl81NjVfR1JFRU5fTUFTSykgPj4gRkkxNl81NjVfR1JFRU5fU0hJRlQpICogMHhGRikgLyAweDNGKTsKCQl0YXJnZXRbRklfUkdCQV9CTFVFXSAgPSAoQllURSkoKCgoYml0c1tjb2xzXSAmIEZJMTZfNTY1X0JMVUVfTUFTSykgPj4gRkkxNl81NjVfQkxVRV9TSElGVCkgKiAweEZGKSAvIDB4MUYpOwoKCQl0YXJnZXQgKz0gMzsKCX0KfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRMaW5lMzJUbzI0KEJZVEUgKnRhcmdldCwgQllURSAqc291cmNlLCBpbnQgd2lkdGhfaW5fcGl4ZWxzKSB7Cglmb3IgKGludCBjb2xzID0gMDsgY29scyA8IHdpZHRoX2luX3BpeGVsczsgY29scysrKSB7CgkJdGFyZ2V0W0ZJX1JHQkFfQkxVRV0gPSBzb3VyY2VbRklfUkdCQV9CTFVFXTsKCQl0YXJnZXRbRklfUkdCQV9HUkVFTl0gPSBzb3VyY2VbRklfUkdCQV9HUkVFTl07CgkJdGFyZ2V0W0ZJX1JHQkFfUkVEXSA9IHNvdXJjZVtGSV9SR0JBX1JFRF07CgoJCXRhcmdldCArPSAzOwoJCXNvdXJjZSArPSA0OwoJfQp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgc21hcnQgY29udmVydCBYIHRvIDI0IGJpdHMKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0NvbnZlcnRUbzI0Qml0cyhGSUJJVE1BUCAqZGliKSB7CglpZighZGliKSByZXR1cm4gTlVMTDsKCgljb25zdCB1bnNpZ25lZCBicHAgPSBGcmVlSW1hZ2VfR2V0QlBQKGRpYik7CgoJY29uc3QgRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYik7CglpZigoaW1hZ2VfdHlwZSAhPSBGSVRfQklUTUFQKSAmJiAoaW1hZ2VfdHlwZSAhPSBGSVRfUkdCMTYpKSB7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJaWYgKGJwcCAhPSAyNCkgewoJCWNvbnN0IGludCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpOwoJCWNvbnN0IGludCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7CgkJRklCSVRNQVAgKm5ld19kaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod2lkdGgsIGhlaWdodCwgMjQsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoKCQlpZihuZXdfZGliID09IE5VTEwpIHsKCQkJcmV0dXJuIE5VTEw7CgkJfQoKCQkvLyBjb3B5IG1ldGFkYXRhIGZyb20gc3JjIHRvIGRzdAoJCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKG5ld19kaWIsIGRpYik7CgoJCXN3aXRjaChicHApIHsKCQkJY2FzZSAxIDoKCQkJewoJCQkJZm9yIChpbnQgcm93cyA9IDA7IHJvd3MgPCBoZWlnaHQ7IHJvd3MrKykgewoJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZTFUbzI0KEZyZWVJbWFnZV9HZXRTY2FuTGluZShuZXdfZGliLCByb3dzKSwgRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgcm93cyksIHdpZHRoLCBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpKTsJCQkJCQoJCQkJfQoJCQkJcmV0dXJuIG5ld19kaWI7CgkJCX0KCgkJCWNhc2UgNCA6CgkJCXsKCQkJCWZvciAoaW50IHJvd3MgPSAwOyByb3dzIDwgaGVpZ2h0OyByb3dzKyspIHsKCQkJCQlGcmVlSW1hZ2VfQ29udmVydExpbmU0VG8yNChGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCwgRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKSk7CgkJCQl9CgkJCQlyZXR1cm4gbmV3X2RpYjsKCQkJfQoJCQkJCgkJCWNhc2UgOCA6CgkJCXsKCQkJCWZvciAoaW50IHJvd3MgPSAwOyByb3dzIDwgaGVpZ2h0OyByb3dzKyspIHsKCQkJCQlGcmVlSW1hZ2VfQ29udmVydExpbmU4VG8yNChGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCwgRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKSk7CgkJCQl9CgkJCQlyZXR1cm4gbmV3X2RpYjsKCQkJfQoKCQkJY2FzZSAxNiA6CgkJCXsKCQkJCWZvciAoaW50IHJvd3MgPSAwOyByb3dzIDwgaGVpZ2h0OyByb3dzKyspIHsKCQkJCQlpZiAoKEZyZWVJbWFnZV9HZXRSZWRNYXNrKGRpYikgPT0gRkkxNl81NjVfUkVEX01BU0spICYmIChGcmVlSW1hZ2VfR2V0R3JlZW5NYXNrKGRpYikgPT0gRkkxNl81NjVfR1JFRU5fTUFTSykgJiYgKEZyZWVJbWFnZV9HZXRCbHVlTWFzayhkaWIpID09IEZJMTZfNTY1X0JMVUVfTUFTSykpIHsKCQkJCQkJRnJlZUltYWdlX0NvbnZlcnRMaW5lMTZUbzI0XzU2NShGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJLy8gaW5jbHVkZXMgY2FzZSB3aGVyZSBhbGwgdGhlIG1hc2tzIGFyZSAwCgkJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZTE2VG8yNF81NTUoRnJlZUltYWdlX0dldFNjYW5MaW5lKG5ld19kaWIsIHJvd3MpLCBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCByb3dzKSwgd2lkdGgpOwoJCQkJCX0KCQkJCX0KCQkJCXJldHVybiBuZXdfZGliOwoJCQl9CgoJCQljYXNlIDMyIDoKCQkJewoJCQkJZm9yIChpbnQgcm93cyA9IDA7IHJvd3MgPCBoZWlnaHQ7IHJvd3MrKykgewoJCQkJCUZyZWVJbWFnZV9Db252ZXJ0TGluZTMyVG8yNChGcmVlSW1hZ2VfR2V0U2NhbkxpbmUobmV3X2RpYiwgcm93cyksIEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHJvd3MpLCB3aWR0aCk7CgkJCQl9CgkJCQlyZXR1cm4gbmV3X2RpYjsKCQkJfQoKCQkJY2FzZSA0ODoKCQkJewoJCQkJY29uc3QgdW5zaWduZWQgc3JjX3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKGRpYik7CgkJCQljb25zdCB1bnNpZ25lZCBkc3RfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2gobmV3X2RpYik7CgkJCQljb25zdCBCWVRFICpzcmNfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKGRpYik7CgkJCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKG5ld19kaWIpOwoJCQkJZm9yIChpbnQgcm93cyA9IDA7IHJvd3MgPCBoZWlnaHQ7IHJvd3MrKykgewoJCQkJCWNvbnN0IEZJUkdCMTYgKnNyY19waXhlbCA9IChGSVJHQjE2KilzcmNfYml0czsKCQkJCQlSR0JUUklQTEUgKmRzdF9waXhlbCA9IChSR0JUUklQTEUqKWRzdF9iaXRzOwoJCQkJCWZvcihpbnQgY29scyA9IDA7IGNvbHMgPCB3aWR0aDsgY29scysrKSB7CgkJCQkJCWRzdF9waXhlbFtjb2xzXS5yZ2J0UmVkICAgPSAoQllURSkoc3JjX3BpeGVsW2NvbHNdLnJlZCAgID4+IDgpOwoJCQkJCQlkc3RfcGl4ZWxbY29sc10ucmdidEdyZWVuID0gKEJZVEUpKHNyY19waXhlbFtjb2xzXS5ncmVlbiA+PiA4KTsKCQkJCQkJZHN0X3BpeGVsW2NvbHNdLnJnYnRCbHVlICA9IChCWVRFKShzcmNfcGl4ZWxbY29sc10uYmx1ZSAgPj4gOCk7CgkJCQkJfQoJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQl9CgkJCQlyZXR1cm4gbmV3X2RpYjsKCQkJfQoJCX0KCX0KCglyZXR1cm4gRnJlZUltYWdlX0Nsb25lKGRpYik7Cn0K