LyoKICogIENvcHlyaWdodCAoQykgMjAwNiBU9nL2ayBFZHdpbiA8ZWR3aW5AY2xhbWF2Lm5ldD4KICoKICogIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhcyAKICogIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgogKgogKiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiAgRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLAogKiAgTUEgMDIxMTAtMTMwMSwgVVNBLgogKi8KCiNpZiBIQVZFX0NPTkZJR19ICiNpbmNsdWRlICJjbGFtYXYtY29uZmlnLmgiCiNlbmRpZgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCiNpZmRlZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCgojaW5jbHVkZSAib3RoZXJzLmgiCiNpbmNsdWRlICJydGYuaCIKI2luY2x1ZGUgImNsYW1hdi5oIgojaW5jbHVkZSAidGFibGUuaCIKI2luY2x1ZGUgInNjYW5uZXJzLmgiCiNpbmNsdWRlICJ2YmFfZXh0cmFjdC5oIgoKZW51bSBwYXJzZV9zdGF0ZSB7IFBBUlNFX01BSU4sIFBBUlNFX0NPTlRST0xfLCBQQVJTRV9DT05UUk9MX1dPUkQsIFBBUlNFX0NPTlRST0xfU1lNQk9MLCBQQVJTRV9DT05UUk9MX1dPUkRfUEFSQU0sIFBBUlNFX0lOVEVSUFJFVF9DT05UUk9MV09SRCB9OwoKZW51bSBydGZfYWN0aW9uCnsKCVJURl9PQkpFQ1QsCglSVEZfT0JKRUNUX0RBVEEKfTsKCnN0cnVjdCBydGZfc3RhdGU7CnR5cGVkZWYgaW50ICgqcnRmX2NhbGxiYWNrX2JlZ2luKShzdHJ1Y3QgcnRmX3N0YXRlKiwgY2xpX2N0eCogY3R4LGNvbnN0IGNoYXIqIHRtcGRpcik7CnR5cGVkZWYgaW50ICgqcnRmX2NhbGxiYWNrX3Byb2Nlc3MpKHN0cnVjdCBydGZfc3RhdGUqLCBjb25zdCB1bnNpZ25lZCBjaGFyKiBkYXRhLGNvbnN0IHNpemVfdCBsZW4pOwp0eXBlZGVmIGludCAoKnJ0Zl9jYWxsYmFja19lbmQpKHN0cnVjdCBydGZfc3RhdGUqLCBjbGlfY3R4Kik7CgpzdHJ1Y3QgcnRmX3N0YXRlIHsKCXNpemVfdCBkZWZhdWx0X2VsZW1lbnRzOwoJc2l6ZV90IGNvbnRyb2x3b3JkX2NudDsKCXNzaXplX3QgY29udHJvbHdvcmRfcGFyYW07CgllbnVtIHBhcnNlX3N0YXRlIHBhcnNlX3N0YXRlOwoJaW50ICBjb250cm9sd29yZF9wYXJhbV9zaWduOwoJaW50ICBlbmNvdW50ZXJlZFRvcExldmVsOy8qIGVuY291bnRlcmVkIHRvcC1sZXZlbCBjb250cm9sIHdvcmRzIHRoYXQgd2UgY2FyZSBhYm91dCAqLwoJY2hhciBjb250cm9sd29yZFszM107CglydGZfY2FsbGJhY2tfYmVnaW4gY2JfYmVnaW47LyogbXVzdCBiZSBub24tbnVsbCBpZiB5b3Ugd2FudCBjYl9wcm9jZXNzLCBhbmQgY2JfZW5kIHRvIGJlIGNhbGxlZCwgYWxzbyBpdCBtdXN0IGNoYW5nZSBjYl9kYXRhIHRvIG5vbi1udWxsICovCglydGZfY2FsbGJhY2tfcHJvY2VzcyBjYl9wcm9jZXNzOwoJcnRmX2NhbGxiYWNrX2VuZCBjYl9lbmQ7Cgl2b2lkKiBjYl9kYXRhOy8qIGRhdGEgc2V0IHVwIGJ5IGNiX2JlZ2luLCB1c2VkIGJ5IGNiX3Byb2Nlc3MsIGFuZCBjbGVhbmVkIHVwIGJ5IGNiX2VuZC4gdHlwaWNhbGx5IHN0YXRlIGRhdGEgKi8KfTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcnRmX3N0YXRlIGJhc2Vfc3RhdGUgPSB7CgkwLDAsMCxQQVJTRV9NQUlOLDAsMCwiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIixOVUxMLE5VTEwsTlVMTCxOVUxMCn07CgpzdHJ1Y3Qgc3RhY2sgewoJc3RydWN0IHJ0Zl9zdGF0ZSogc3RhdGVzOwoJc2l6ZV90IGVsZW1lbnRzOwoJc2l6ZV90IHN0YWNrX2NudDsKCXNpemVfdCBzdGFja19zaXplOwoJaW50ICAgIHdhcm5lZDsKfTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcnRmX2FjdGlvbl9tYXBwaW5nIHsKCWNvbnN0IGNoYXIqIGNvbnRyb2x3b3JkOwoJY29uc3QgZW51bSBydGZfYWN0aW9uIGFjdGlvbjsKfSBydGZfYWN0aW9uX21hcHBpbmcgW10gPSAKewoJeyJvYmplY3QiLCBSVEZfT0JKRUNUfSwKCXsib2JqZGF0YSAiLFJURl9PQkpFQ1RfREFUQX0KfTsKCnN0YXRpYyBjb25zdCBzaXplX3QgcnRmX2FjdGlvbl9tYXBwaW5nX2NudCA9IHNpemVvZihydGZfYWN0aW9uX21hcHBpbmcpL3NpemVvZihydGZfYWN0aW9uX21hcHBpbmdbMF0pOwoKZW51bSBydGZfb2JqZGF0YV9zdGF0ZSB7V0FJVF9NQUdJQywgV0FJVF9ERVNDX0xFTiwgV0FJVF9ERVNDLCBXQUlUX1pFUk8sIFdBSVRfREFUQV9TSVpFLCBEVU1QX0RBVEEsIERVTVBfRElTQ0FSRH07CnN0YXRpYyBjb25zdCB1bnNpZ25lZCBjaGFyIHJ0Zl9kYXRhX21hZ2ljW10gPSB7MHgwMSwgMHgwNSwgMHgwMCwgMHgwMCwgMHgwMiwgMHgwMCwgMHgwMCwgMHgwMH07LyogaXMgdGhpcyBhIG1hZ2ljIG51bWJlciwgb3IgZG9lcyBpdCBtZWFuIHNvbWV0aGluZyAqLwpzdGF0aWMgY29uc3Qgc2l6ZV90IHJ0Zl9kYXRhX21hZ2ljX2xlbiAgPSBzaXplb2YocnRmX2RhdGFfbWFnaWMpOwoKc3RydWN0IHJ0Zl9vYmplY3RfZGF0YSB7CgljaGFyKiBuYW1lOwoJaW50ICBmZDsKCWludCBwYXJ0aWFsOwoJaW50IGhhc19wYXJ0aWFsOwoJZW51bSBydGZfb2JqZGF0YV9zdGF0ZSBpbnRlcm5hbF9zdGF0ZTsKCWNoYXIqIGRlc2NfbmFtZTsKCWNvbnN0IGNoYXIqIHRtcGRpcjsKCWNsaV9jdHgqICAgIGN0eDsKCXNpemVfdCBkZXNjX2xlbjsKCXNpemVfdCBicmVhZDsKfTsKCiNkZWZpbmUgQlVGRl9TSVpFIDgxOTIKLyogZ2VuZXJhdGVkIGJ5IGNvbnRyaWIvcGhpc2hpbmcvZ2VuZXJhdGVfdGFibGVzLmMgKi8Kc3RhdGljIGNvbnN0IHNob3J0IGludCBoZXh0YWJsZVsyNTZdID0gewogICAgICAgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAKICAgICAgIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgCiAgICAgICAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIAogICAgICAgMHgwLCAweDEsIDB4MiwgMHgzLCAweDQsIDB4NSwgMHg2LCAweDcsIDB4OCwgMHg5LCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAKICAgICAgIDB4MCwgMHhhLCAweGIsIDB4YywgMHhkLCAweGUsIDB4ZiwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgCiAgICAgICAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIAogICAgICAgMHgwLCAweGEsIDB4YiwgMHhjLCAweGQsIDB4ZSwgMHhmLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAKICAgICAgIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgCiAgICAgICAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIAogICAgICAgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAKICAgICAgIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgCiAgICAgICAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIAogICAgICAgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAKICAgICAgIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgCiAgICAgICAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIAogICAgICAgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwLCAweDAsIDB4MCwgMHgwCn07CgpzdGF0aWMgdm9pZCBpbml0X3J0Zl9zdGF0ZShzdHJ1Y3QgcnRmX3N0YXRlKiBzdGF0ZSkKewoJKnN0YXRlID0gYmFzZV9zdGF0ZTsKCXN0YXRlLT5wYXJzZV9zdGF0ZSA9IFBBUlNFX01BSU47CglzdGF0ZS0+Y29udHJvbHdvcmRfY250ID0gMDsKfQoKc3RhdGljIGludCBjb21wYXJlX3N0YXRlKGNvbnN0IHN0cnVjdCBydGZfc3RhdGUqIGEsY29uc3Qgc3RydWN0IHJ0Zl9zdGF0ZSogYikKewoJcmV0dXJuIChhLT5jb250cm9sd29yZF9wYXJhbSA9PSBiLT5jb250cm9sd29yZF9wYXJhbSAmJiAKCQkJYS0+cGFyc2Vfc3RhdGUgPT0gYi0+cGFyc2Vfc3RhdGUgJiYKCQkJYS0+ZW5jb3VudGVyZWRUb3BMZXZlbCA9PSBiLT5lbmNvdW50ZXJlZFRvcExldmVsICYmCgkJCW1lbWNtcChhLT5jb250cm9sd29yZCxiLT5jb250cm9sd29yZCwzMyk9PTAgJiYKCQkJYS0+Y2JfYmVnaW4gPT0gYi0+Y2JfYmVnaW4gJiYKCQkJYS0+Y2JfcHJvY2VzcyA9PSBiLT5jYl9wcm9jZXNzICYmCgkJCWEtPmNiX2VuZCA9PSBiLT5jYl9lbmQgJiYKCQkJYS0+Y2JfZGF0YSA9PSBiLT5jYl9kYXRhKTsKfQoKCnN0YXRpYyBpbnQgcHVzaF9zdGF0ZShzdHJ1Y3Qgc3RhY2sqIHN0YWNrLHN0cnVjdCBydGZfc3RhdGUqIHN0YXRlKQp7CglpbnQgdG9wbGV2ZWw7CglzaXplX3QgZGVmZWxlbWVudHM7CgoJc3RhY2stPmVsZW1lbnRzKys7CglpZiggY29tcGFyZV9zdGF0ZShzdGF0ZSwmYmFzZV9zdGF0ZSkpIHsgCgkJc3RhdGUtPmRlZmF1bHRfZWxlbWVudHMrKzsKCQlyZXR1cm4gMDsvKiB0aGlzIGlzIGRlZmF1bHQgc3RhdGUsIGRvbid0IHB1c2ggaXQsIHdlJ2xsIGtub3cgd2hlbiB3ZSBwb3AgaXQgdGhhdCBpdCB3YXMgdGhlIGRlZmF1bHQgb25lLAoJCQkgIHdlIHN0b3JlIGluIHRoZSBzdGF0ZSBob3cgbWFueSBkZWZhdWx0IGVsZW1lbnRzIHdlIGhhdmUgb24gdGhlIHN0YWNrICovCgl9CglpZihzdGFjay0+c3RhY2tfY250ID49IHN0YWNrLT5zdGFja19zaXplKSB7CgkJLyogZ3JvdyBzdGFjayAqLwoJCXN0YWNrLT5zdGFja19zaXplICs9IDEyODsKCQlzdGFjay0+c3RhdGVzID0gY2xpX3JlYWxsb2MyKHN0YWNrLT5zdGF0ZXMsIHN0YWNrLT5zdGFja19zaXplKnNpemVvZigqc3RhY2stPnN0YXRlcykpOwoJCWlmKCFzdGFjay0+c3RhdGVzKQoJCQlyZXR1cm4gQ0xfRU1FTTsKCX0KCXN0YWNrLT5zdGF0ZXNbc3RhY2stPnN0YWNrX2NudCsrXSA9ICpzdGF0ZTsKCXRvcGxldmVsID0gc3RhdGUtPmVuY291bnRlcmVkVG9wTGV2ZWw7CglkZWZlbGVtZW50cyA9IHN0YXRlLT5kZWZhdWx0X2VsZW1lbnRzOwoKCSpzdGF0ZSA9IGJhc2Vfc3RhdGU7CgoJc3RhdGUtPmVuY291bnRlcmVkVG9wTGV2ZWwgPSB0b3BsZXZlbDsKCXN0YXRlLT5kZWZhdWx0X2VsZW1lbnRzID0gZGVmZWxlbWVudHM7CglyZXR1cm4gMDsgCn0KCgpzdGF0aWMgaW50IHBvcF9zdGF0ZShzdHJ1Y3Qgc3RhY2sqIHN0YWNrLHN0cnVjdCBydGZfc3RhdGUqIHN0YXRlKQp7CglzdGFjay0+ZWxlbWVudHMtLTsKCWlmKHN0YXRlLT5kZWZhdWx0X2VsZW1lbnRzKSB7CgkJY29uc3Qgc2l6ZV90IGRlZmF1bHRfZWxlbWVudHMgPSBzdGF0ZS0+ZGVmYXVsdF9lbGVtZW50cy0xOwoJCWNvbnN0IGludCB0b3BsZXZlbCA9IHN0YXRlLT5lbmNvdW50ZXJlZFRvcExldmVsOwoJCSpzdGF0ZSA9IGJhc2Vfc3RhdGU7CgkJc3RhdGUtPmRlZmF1bHRfZWxlbWVudHMgPSBkZWZhdWx0X2VsZW1lbnRzOwoJCXN0YXRlLT5lbmNvdW50ZXJlZFRvcExldmVsID0gdG9wbGV2ZWw7CgkJcmV0dXJuIDA7LyogdGhpcyBpcyBhIGRlZmF1bHQgJ3N0YXRlJyovCgl9CglpZighc3RhY2stPnN0YWNrX2NudCkgewoJCWlmKCFzdGFjay0+d2FybmVkKSB7CgkJCWNsaV9kYmdtc2coIldhcm5pbmc6IGF0dGVtcHQgdG8gcG9wIGZyb20gZW1wdHkgc3RhY2shXG4iKTsKCQkJc3RhY2stPndhcm5lZCA9IDE7CgkJfQoJCSpzdGF0ZSA9IGJhc2Vfc3RhdGU7LyogbGV0cyBhc3N1bWUgd2UgZ2l2ZSBpdCBhIGJhc2Ugc3RhdGUgKi8KCQlyZXR1cm4gMDsKCX0KCSpzdGF0ZSA9IHN0YWNrLT5zdGF0ZXNbLS1zdGFjay0+c3RhY2tfY250XTsKCXJldHVybiAwOwp9CgoKc3RhdGljIGludCBsb2FkX2FjdGlvbnModGFibGVfdCogdCkKewoJc2l6ZV90IGk7Cglmb3IoaT0wOyBpPHJ0Zl9hY3Rpb25fbWFwcGluZ19jbnQ7IGkrKykKCQlpZih0YWJsZUluc2VydCh0LCBydGZfYWN0aW9uX21hcHBpbmdbaV0uY29udHJvbHdvcmQsIHJ0Zl9hY3Rpb25fbWFwcGluZ1tpXS5hY3Rpb24pID09IC0xKQoJCQlyZXR1cm4gLTE7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBydGZfb2JqZWN0X2JlZ2luKHN0cnVjdCBydGZfc3RhdGUqIHN0YXRlLGNsaV9jdHgqIGN0eCxjb25zdCBjaGFyKiB0bXBkaXIpCnsKCXN0cnVjdCBydGZfb2JqZWN0X2RhdGEqIGRhdGEgPSBjbGlfbWFsbG9jKHNpemVvZigqZGF0YSkpOwoJaWYoIWRhdGEpCgkJcmV0dXJuIENMX0VNRU07CglkYXRhLT5mZCA9IC0xOwoJZGF0YS0+cGFydGlhbCA9IDA7CglkYXRhLT5oYXNfcGFydGlhbCA9IDA7CglkYXRhLT5icmVhZCA9IDA7CglkYXRhLT5pbnRlcm5hbF9zdGF0ZSA9IFdBSVRfTUFHSUM7CglkYXRhLT50bXBkaXIgPSB0bXBkaXI7CglkYXRhLT5jdHggICAgPSBjdHg7CglkYXRhLT5uYW1lICAgPSBOVUxMOwoJZGF0YS0+ZGVzY19uYW1lID0gTlVMTDsKCglzdGF0ZS0+Y2JfZGF0YSA9IGRhdGE7CglyZXR1cm4gMDsKfQoKCnN0YXRpYyBpbnQgZGVjb2RlX2FuZF9zY2FuKHN0cnVjdCBydGZfb2JqZWN0X2RhdGEqIGRhdGEsIGNsaV9jdHgqIGN0eCkKewoJaW50IG9mZCwgcmV0PTA7CgoJY2xpX2RiZ21zZygiUlRGOlNjYW5uaW5nIGVtYmVkZGVkIG9iamVjdDolc1xuIixkYXRhLT5uYW1lKTsKCWlmKGRhdGEtPmJyZWFkID09IDEgJiYgZGF0YS0+ZmQgPiAwKSB7CgkJY2xpX2RiZ21zZygiRGVjb2Rpbmcgb2xlIG9iamVjdFxuIik7CgkJbHNlZWsoZGF0YS0+ZmQsMCxTRUVLX1NFVCk7CgkJb2ZkID0gY2xpX2RlY29kZV9vbGVfb2JqZWN0KGRhdGEtPmZkLGRhdGEtPnRtcGRpcik7CgkJaWYgKG9mZCA+PSAwKSB7CgkJCXJldCA9IGNsaV9tYWdpY19zY2FuZGVzYyhvZmQsIGN0eCk7CgkJCWNsb3NlKG9mZCk7CgkJfQoJfQoJZWxzZSBpZihkYXRhLT5mZCA+IDApCgkJcmV0ID0gY2xpX21hZ2ljX3NjYW5kZXNjKGRhdGEtPmZkLGN0eCk7CglpZihkYXRhLT5mZCA+IDApCgljbG9zZShkYXRhLT5mZCk7CglkYXRhLT5mZCA9IC0xOwoJaWYoZGF0YS0+bmFtZSkgewoJCWlmKCFjbGlfbGVhdmV0ZW1wc19mbGFnKQoJCQl1bmxpbmsoZGF0YS0+bmFtZSk7CgkJZnJlZShkYXRhLT5uYW1lKTsKCQlkYXRhLT5uYW1lID0gTlVMTDsKCX0KCglpZihyZXQgIT0gQ0xfQ0xFQU4pCgkJcmV0dXJuIHJldDsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJ0Zl9vYmplY3RfcHJvY2VzcyhzdHJ1Y3QgcnRmX3N0YXRlKiBzdGF0ZSwgY29uc3QgdW5zaWduZWQgY2hhciogaW5wdXQsY29uc3Qgc2l6ZV90IGxlbikKewoJc3RydWN0IHJ0Zl9vYmplY3RfZGF0YSogZGF0YSA9IHN0YXRlLT5jYl9kYXRhOwoJdW5zaWduZWQgY2hhciBvdXRkYXRhW0JVRkZfU0laRV07Cgljb25zdCB1bnNpZ25lZCBjaGFyKiBvdXRfZGF0YTsKCXNpemVfdCBvdXRfY250ID0gMDsKCXNpemVfdCBpOwoJaW50IHJldDsKCglpZighZGF0YSB8fCAhbGVuKQoJCXJldHVybiAwOwoKCWlmKGRhdGEtPmhhc19wYXJ0aWFsKSB7CgkJZm9yKGk9MDtpPGxlbiAmJiAhaXN4ZGlnaXQoaW5wdXRbaV0pO2krKykKCQkJOwoJCWlmKGk8bGVuKSB7CgkJCW91dGRhdGFbb3V0X2NudCsrXSA9IGRhdGEtPnBhcnRpYWwgfCBoZXh0YWJsZVtpbnB1dFtpKytdXTsKCQkJZGF0YS0+aGFzX3BhcnRpYWwgPSAwOwoJCX0KCQllbHNlCgkJCXJldHVybiAwOwoJfQoJZWxzZQoJCWkgPSAwOwoKCWZvcig7aTxsZW47aSsrKSB7CgkJaWYoaXN4ZGlnaXQoaW5wdXRbaV0pKSB7CgkJCQljb25zdCB1bnNpZ25lZCBjaGFyIGJ5dGUgPSBoZXh0YWJsZVsgaW5wdXRbaSsrXSBdIDw8IDQ7CgkJCQl3aGlsZShpPGxlbiAmJiAhaXN4ZGlnaXQoaW5wdXRbaV0pKQoJCQkJCWkrKzsKCQkJCWlmKGkgPT0gbGVuKSB7CgkJCQkJZGF0YS0+cGFydGlhbCA9IGJ5dGU7CgkJCQkJZGF0YS0+aGFzX3BhcnRpYWwgPSAxOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJb3V0ZGF0YVtvdXRfY250KytdID0gYnl0ZSB8IGhleHRhYmxlWyBpbnB1dFtpXSBdOwoJCX0KCX0KCglvdXRfZGF0YSA9IG91dGRhdGE7Cgl3aGlsZShvdXRfZGF0YSAmJiBvdXRfY250KSB7CgkJc3dpdGNoKGRhdGEtPmludGVybmFsX3N0YXRlKSB7CgkJCWNhc2UgV0FJVF9NQUdJQzogewoJCQkJCQkgY2xpX2RiZ21zZygiUlRGOiB3YWl0aW5nIGZvciBtYWdpY1xuIik7CgkJCQkJCSBmb3IoaT0wOyBpPG91dF9jbnQgJiYgZGF0YS0+YnJlYWQgPCBydGZfZGF0YV9tYWdpY19sZW47IGkrKywgZGF0YS0+YnJlYWQrKykKCQkJCQkJCSBpZihydGZfZGF0YV9tYWdpY1tkYXRhLT5icmVhZF0gIT0gb3V0X2RhdGFbaV0pIHsKCQkJCQkJCQkgY2xpX2RiZ21zZygiV2FybmluZzogcnRmIG9iamRhdGEgbWFnaWMgbnVtYmVyIG5vdCBtYXRjaGVkLCBleHBlY3RlZDolZCwgZ290OiAlZCwgYXQgcG9zOiVsdVxuIixydGZfZGF0YV9tYWdpY1tpXSxvdXRfZGF0YVtpXSxkYXRhLT5icmVhZCk7CgkJCQkJCQkgfQoJCQkJCQkgb3V0X2NudCAgLT0gaTsKCQkJCQkJIGlmKGRhdGEtPmJyZWFkID09IHJ0Zl9kYXRhX21hZ2ljX2xlbikgewoJCQkJCQkJIG91dF9kYXRhICs9IGk7CgkJCQkJCQkgZGF0YS0+YnJlYWQgPSAwOwoJCQkJCQkJIGRhdGEtPmludGVybmFsX3N0YXRlID0gV0FJVF9ERVNDX0xFTjsJCQkJCQkgCgkJCQkJCSB9CgkJCQkJCSBicmVhazsKCQkJCQkgfQoJCQljYXNlIFdBSVRfREVTQ19MRU46IHsKCQkJCQkJICAgIGlmKGRhdGEtPmJyZWFkID09IDApCgkJCQkJCQkgICAgZGF0YS0+ZGVzY19sZW4gPSAwOwoJCQkJCQkgICAgZm9yKGk9MDsgaTxvdXRfY250ICYmIGRhdGEtPmJyZWFkIDwgNDsgaSsrLGRhdGEtPmJyZWFkKyspCgkJCQkJCQkgICAgZGF0YS0+ZGVzY19sZW4gIHw9ICAoKHNpemVfdClvdXRfZGF0YVtpXSkgPDwgKGRhdGEtPmJyZWFkKjgpOwoJCQkJCQkgICAgb3V0X2NudCAgLT0gaTsKCQkJCQkJICAgIGlmKGRhdGEtPmJyZWFkID09IDQpIHsKCQkJCQkJCSAgICBvdXRfZGF0YSArPSBpOwoJCQkJCQkJICAgIGRhdGEtPmJyZWFkPTA7CgkJCQkJCQkgICAgaWYoZGF0YS0+ZGVzY19sZW4gPiA2NCkgewoJCQkJCQkJCSAgICBjbGlfZGJnbXNnKCJEZXNjcmlwdGlvbiBsZW5ndGggdG9vIGJpZyAoJWx1KSwgc2hvd2luZyBvbmx5IDY0IGJ5dGVzIG9mIGl0XG4iLGRhdGEtPmRlc2NfbGVuKTsKCQkJCQkJCQkgICAgZGF0YS0+ZGVzY19uYW1lID0gY2xpX21hbGxvYyg2NSk7CgkJCQkJCQkgICAgfQoJCQkJCQkJICAgIGVsc2UKCQkJCQkJCQkgICAgZGF0YS0+ZGVzY19uYW1lID0gY2xpX21hbGxvYyhkYXRhLT5kZXNjX2xlbisxKTsKCQkJCQkJCSAgICBpZighZGF0YS0+ZGVzY19uYW1lKSB7CgkJCQkJCQkJICAgIHJldHVybiBDTF9FTUVNOwoJCQkJCQkJICAgIH0KCQkJCQkJCSAgICBkYXRhLT5pbnRlcm5hbF9zdGF0ZSA9IFdBSVRfREVTQzsKCQkJCQkJCSAgICBjbGlfZGJnbXNnKCJSVEY6IGRlc2NyaXB0aW9uIGxlbmd0aDolbHVcbiIsZGF0YS0+ZGVzY19sZW4pOwoJCQkJCQkgICAgfQoJCQkJCQkgICAgYnJlYWs7CgkJCQkJICAgIH0KCQkJY2FzZSBXQUlUX0RFU0M6ewoJCQkJCSAgICAgICBjbGlfZGJnbXNnKCJSVEY6IGluIFdBSVRfREVTQ1xuIik7CgkJCQkJICAgICAgIGZvcihpPTA7aTxvdXRfY250ICYmIGRhdGEtPmJyZWFkIDwgZGF0YS0+ZGVzY19sZW4gJiYgZGF0YS0+YnJlYWQgPCA2NDtpKyssIGRhdGEtPmJyZWFkKyspCgkJCQkJCSAgICAgICBkYXRhLT5kZXNjX25hbWVbZGF0YS0+YnJlYWRdID0gb3V0X2RhdGFbaV07CgkJCQkJICAgICAgIG91dF9jbnQgLT0gaTsKCQkJCQkgICAgICAgb3V0X2RhdGEgKz0gaTsKCQkJCQkgICAgICAgaWYoZGF0YS0+YnJlYWQgPCBkYXRhLT5kZXNjX2xlbiAmJiBkYXRhLT5icmVhZCA8IDY0KSB7CgkJCQkJCSAgICAgICBjbGlfZGJnbXNnKCJSVEY6IHdhaXRpbmcgZm9yIG1vcmUgZGF0YSgxKVxuIik7CgkJCQkJCSAgICAgICByZXR1cm4gMDsvKiB3YWl0IGZvciBtb3JlIGRhdGEgKi8KCQkJCQkgICAgICAgfQoJCQkJCQkgICAgICAgZGF0YS0+ZGVzY19uYW1lW2RhdGEtPmJyZWFkXSA9ICdcMCc7CgkJCQkJICAgICAgIGlmKGRhdGEtPmRlc2NfbGVuIC0gZGF0YS0+YnJlYWQgPiBvdXRfY250KSB7CgkJCQkJCSAgICAgICBkYXRhLT5kZXNjX2xlbiAtPSBvdXRfY250OwoJCQkJCQkgICAgICAgY2xpX2RiZ21zZygiUlRGOiB3YWl0aW5nIGZvciBtb3JlIGRhdGEoMilcbiIpOwoJCQkJCQkgICAgICAgcmV0dXJuIDA7Lyogd2FpdCBmb3IgbW9yZSBkYXRhICovCgkJCQkJICAgICAgIH0KCQkJCQkgICAgICAgb3V0X2NudCAgLT0gZGF0YS0+ZGVzY19sZW4gLSBkYXRhLT5icmVhZDsKCQkJCQkgICAgICAgaWYoZGF0YS0+YnJlYWQgPj0gZGF0YS0+ZGVzY19sZW4pIHsKCQkJCQkJICAgICAgIG91dF9kYXRhICs9IGRhdGEtPmRlc2NfbGVuIC0gZGF0YS0+YnJlYWQ7CgkJCQkJCSAgICAgICBkYXRhLT5icmVhZCA9IDA7CgkJCQkJCSAgICAgICBjbGlfZGJnbXNnKCJQcmVwYXJpbmcgdG8gZHVtcCBydGYgZW1iZWRkZWQgb2JqZWN0LCBkZXNjcmlwdGlvbjolc1xuIixkYXRhLT5kZXNjX25hbWUpOwoJCQkJCQkgICAgICAgZnJlZShkYXRhLT5kZXNjX25hbWUpOwoJCQkJCQkgICAgICAgZGF0YS0+ZGVzY19uYW1lID0gTlVMTDsKCQkJCQkJICAgICAgIGRhdGEtPmludGVybmFsX3N0YXRlID0gV0FJVF9aRVJPOwoJCQkJCSAgICAgICB9CgkJCQkJICAgICAgIGJyZWFrOwoJCQkJICAgICAgIH0KCQkJY2FzZSBXQUlUX1pFUk86ewoJCQkJCSAgICAgICBpZihvdXRfY250IDwgOC1kYXRhLT5icmVhZCkgewoJCQkJCQkgICAgICAgb3V0X2NudCA9IDA7CgkJCQkJCSAgICAgICBkYXRhLT5icmVhZCArPSBvdXRfY250OwoJCQkJCSAgICAgICB9CgkJCQkJICAgICAgIGVsc2UgewoJCQkJCQkgICAgICAgb3V0X2NudCAgLT0gOC1kYXRhLT5icmVhZDsKCQkJCQkJICAgICAgIGRhdGEtPmJyZWFkID0gODsKCQkJCQkgICAgICAgfQoJCQkJCSAgICAgICBpZihkYXRhLT5icmVhZCA9PSA4KSB7CgkJCQkJCSAgICAgICBvdXRfZGF0YSArPSA4OwoJCQkJCQkgICAgICAgZGF0YS0+YnJlYWQgPSAwOwoJCQkJCQkgICAgICAgY2xpX2RiZ21zZygiUlRGOiBuZXh0IHN0YXRlOiB3YWl0X2RhdGFfc2l6ZVxuIik7CgkJCQkJCSAgICAgICBkYXRhLT5pbnRlcm5hbF9zdGF0ZSA9IFdBSVRfREFUQV9TSVpFOwoJCQkJCSAgICAgICB9CgkJCQkJICAgICAgIGJyZWFrOwoJCQkJICAgICAgIH0KCgkJCWNhc2UgV0FJVF9EQVRBX1NJWkU6IHsKCQkJCQkJICAgICBjbGlfZGJnbXNnKCJSVEY6IGluIFdBSVRfREFUQV9TSVpFXG4iKTsKCQkJCQkJICAgIGlmKGRhdGEtPmJyZWFkID09IDApCgkJCQkJCQkgICAgZGF0YS0+ZGVzY19sZW4gPSAwOwoJCQkJCQkgICAgZm9yKGk9MDsgaTxvdXRfY250ICYmIGRhdGEtPmJyZWFkIDwgNDsgaSsrLGRhdGEtPmJyZWFkKyspCgkJCQkJCQkgICAgZGF0YS0+ZGVzY19sZW4gIHw9ICgoc2l6ZV90KW91dF9kYXRhW2ldKSA8PCAoOCpkYXRhLT5icmVhZCk7CgkJCQkJCSAgICBvdXRfY250ICAtPSBpOwoJCQkJCQkgICAgaWYoZGF0YS0+YnJlYWQgPT0gNCkgewoJCQkJCQkJICAgIG91dF9kYXRhICs9IGk7CgkJCQkJCQkgICAgZGF0YS0+YnJlYWQ9MDsKCQkJCQkJCSAgICBjbGlfZGJnbXNnKCJEdW1waW5nIHJ0ZiBlbWJlZGRlZCBvYmplY3Qgb2Ygc2l6ZTolbHVcbiIsZGF0YS0+ZGVzY19sZW4pOwoJCQkJCQkJICAgIGlmKChyZXQgPSBjbGlfZ2VudGVtcGZkKGRhdGEtPnRtcGRpciwgJmRhdGEtPm5hbWUsICZkYXRhLT5mZCkpKQoJCQkJCQkJCSAgICByZXR1cm4gcmV0OwoJCQkJCQkJICAgIGRhdGEtPmludGVybmFsX3N0YXRlID0gRFVNUF9EQVRBOwoJICAgIAkJCQkJCSAgICBjbGlfZGJnbXNnKCJSVEY6IG5leHQgc3RhdGU6IERVTVBfREFUQVxuIik7CgkJCQkJCSAgICB9CgkJCQkJCSAgICBicmVhazsKCQkJCQkgICAgIH0KCQkJY2FzZSBEVU1QX0RBVEE6IHsKCQkJCQkJc3NpemVfdCBvdXRfd2FudCA9IG91dF9jbnQgPCBkYXRhLT5kZXNjX2xlbiA/IG91dF9jbnQgOiBkYXRhLT5kZXNjX2xlbjsKCQkJCQkJaWYoIWRhdGEtPmJyZWFkKSB7CgkJCQkJCQlpZihvdXRfZGF0YVswXSAhPSAweGQwIHx8IG91dF9kYXRhWzFdIT0weGNmKSB7CgkJCQkJCQkJLyogdGhpcyBpcyBub3QgYW4gb2xlMiBkb2MsIGJ1dCBzb21lIG9sZSAoc3RyZWFtPykgdG8gYmUKCQkJCQkJCQkgKiBkZWNvZGVkIGJ5IGNsaV9kZWNvZGVfb2xlX29iamVjdCovCgkJCQkJCQkgICAgY2hhciBvdXRbNF07CgkJCQkJCQkgICAgZGF0YS0+YnJlYWQgPSAxOy8qIGZsYWcgdG8gaW5kaWNhdGUgdGhpcyBuZWVkcyB0byBiZSBzY2FubmVkIHdpdGggY2xpX2RlY29kZV9vbGVfb2JqZWN0Ki8KCQkJCQkJCSAgICBjbGlfd3JpdGVpbnQzMihvdXQsZGF0YS0+ZGVzY19sZW4pOwoJCQkJCQkJICAgIGlmKGNsaV93cml0ZW4oZGF0YS0+ZmQsb3V0LDQpIT00KQoJCQkJCQkJCSAgICByZXR1cm4gQ0xfRUlPOyAKCQkJCQkJCX0KCQkJCQkJCWVsc2UKCQkJCQkJCQlkYXRhLT5icmVhZCA9IDI7CgkJCQkJCX0KCgkJCQkJCWRhdGEtPmRlc2NfbGVuIC09IG91dF93YW50OwoJCQkJCQlpZihjbGlfd3JpdGVuKGRhdGEtPmZkLG91dF9kYXRhLG91dF93YW50KSAhPSBvdXRfd2FudCkgewoJCQkJCQkJcmV0dXJuIENMX0VJTzsKCQkJCQkJfQoJCQkJCQlvdXRfZGF0YSArPSBvdXRfd2FudDsKCQkJCQkJb3V0X2NudCAgLT0gb3V0X3dhbnQ7CgkJCQkJCWlmKCFkYXRhLT5kZXNjX2xlbikgeyAKCQkJCQkJCWludCByYzsKCQkJCQkJCWlmKCggcmMgPSBkZWNvZGVfYW5kX3NjYW4oZGF0YSwgZGF0YS0+Y3R4KSApKQoJCQkJCQkJCXJldHVybiByYzsKCQkJCQkJCWRhdGEtPmJyZWFkPTA7CgkJCQkJCQlkYXRhLT5pbnRlcm5hbF9zdGF0ZSA9IFdBSVRfTUFHSUM7CgkJCQkJCX0KCQkJCQkJYnJlYWs7CQkJCQkKCQkJCQl9CQkJCSAgICAKCQkJY2FzZSBEVU1QX0RJU0NBUkQ6CgkJCWRlZmF1bHQ6CgkJCQkJb3V0X2NudCA9IDA7CgkJCQkJOwoJCX0KCX0KCXJldHVybiAwOwp9CgoKCnN0YXRpYyBpbnQgcnRmX29iamVjdF9lbmQoc3RydWN0IHJ0Zl9zdGF0ZSogc3RhdGUsY2xpX2N0eCogY3R4KQp7CglzdHJ1Y3QgcnRmX29iamVjdF9kYXRhKiBkYXRhID0gc3RhdGUtPmNiX2RhdGE7CglpbnQgcmMgPSAwOwoJaWYoIWRhdGEpCgkJcmV0dXJuIDA7CglpZihkYXRhLT5mZCA+IDApIHsgCgkJcmMgPSBkZWNvZGVfYW5kX3NjYW4oZGF0YSwgY3R4KTsKCX0KCWlmKGRhdGEtPm5hbWUpCgkJZnJlZShkYXRhLT5uYW1lKTsKCWlmKGRhdGEtPmRlc2NfbmFtZSkKCQlmcmVlKGRhdGEtPmRlc2NfbmFtZSk7CglmcmVlKGRhdGEpOwoJc3RhdGUtPmNiX2RhdGEgPSBOVUxMOwoJcmV0dXJuIHJjOwp9CgoKc3RhdGljIHZvaWQgcnRmX2FjdGlvbihzdHJ1Y3QgcnRmX3N0YXRlKiBzdGF0ZSxsb25nIGFjdGlvbikKewoJc3dpdGNoKGFjdGlvbikgewoJCWNhc2UgUlRGX09CSkVDVDoKCQkJc3RhdGUtPmVuY291bnRlcmVkVG9wTGV2ZWwgfD0gMTw8UlRGX09CSkVDVDsKCQkJYnJlYWs7CgkJY2FzZSBSVEZfT0JKRUNUX0RBVEE6CgkJCWlmKHN0YXRlLT5lbmNvdW50ZXJlZFRvcExldmVsICYgKDE8PFJURl9PQkpFQ1QpICkgewoJCQkJc3RhdGUtPmNiX2JlZ2luID0gcnRmX29iamVjdF9iZWdpbjsKCQkJCXN0YXRlLT5jYl9wcm9jZXNzID0gcnRmX29iamVjdF9wcm9jZXNzOwoJCQkJc3RhdGUtPmNiX2VuZCA9IHJ0Zl9vYmplY3RfZW5kOwoJCQl9CgkJCWJyZWFrOwoJfTsKfQoKc3RhdGljIHZvaWQgY2xlYW51cF9zdGFjayhzdHJ1Y3Qgc3RhY2sqIHN0YWNrLHN0cnVjdCBydGZfc3RhdGUqIHN0YXRlLGNsaV9jdHgqIGN0eCkKewoJd2hpbGUoc3RhY2sgJiYgc3RhY2stPnN0YWNrX2NudCAvKiAmJiBzdGF0ZS0+ZGVmYXVsdF9lbGVtZW50cyovKSB7CgkJcG9wX3N0YXRlKHN0YWNrLHN0YXRlKTsKCQlpZihzdGF0ZS0+Y2JfZGF0YSAmJiBzdGF0ZS0+Y2JfZW5kKQoJCQlzdGF0ZS0+Y2JfZW5kKHN0YXRlLGN0eCk7Cgl9Cn0KCgojZGVmaW5lIFNDQU5fQ0xFQU5VUCBcCglpZihzdGF0ZS5jYl9kYXRhICYmIHN0YXRlLmNiX2VuZClcCgkJc3RhdGUuY2JfZW5kKCZzdGF0ZSxjdHgpO1wKCXRhYmxlRGVzdHJveShhY3Rpb250YWJsZSk7XAoJY2xlYW51cF9zdGFjaygmc3RhY2ssJnN0YXRlLGN0eCk7XAoJZnJlZShidWZmKTtcCiAgICAgICAgaWYoIWNsaV9sZWF2ZXRlbXBzX2ZsYWcpXAoJCWNsaV9ybWRpcnModGVtcG5hbWUpO1wKCWZyZWUodGVtcG5hbWUpO1wKCWZyZWUoc3RhY2suc3RhdGVzKTsKCmludCBjbGlfc2NhbnJ0ZihpbnQgZGVzYywgY2xpX2N0eCAqY3R4KQp7CgljaGFyKiB0ZW1wbmFtZTsKCWNvbnN0IHVuc2lnbmVkIGNoYXIqIHB0cjsKCWNvbnN0IHVuc2lnbmVkIGNoYXIqIHB0cl9lbmQ7Cgl1bnNpZ25lZCBjaGFyKiBidWZmOwoJaW50IHJldCA9IENMX0NMRUFOOwoJc3RydWN0IHJ0Zl9zdGF0ZSBzdGF0ZTsKCXN0cnVjdCBzdGFjayBzdGFjazsKCXNzaXplX3QgYnJlYWQ7Cgl0YWJsZV90KiBhY3Rpb250YWJsZTsKCXVpbnQ4X3QgbWFpbl9zeW1ib2xzWzI1Nl07CgoJY2xpX2RiZ21zZygiaW4gY2xpX3NjYW5ydGYoKVxuIik7CgoJbWVtc2V0KG1haW5fc3ltYm9scywgMCwgMjU2KTsKCW1haW5fc3ltYm9sc1sneyddPTE7CgltYWluX3N5bWJvbHNbJ30nXT0xOwoJbWFpbl9zeW1ib2xzWydcXCddPTE7CgoJc3RhY2suc3RhY2tfY250ID0gMDsKCXN0YWNrLnN0YWNrX3NpemUgPSAxNjsKCXN0YWNrLmVsZW1lbnRzID0gMDsKCXN0YWNrLndhcm5lZCA9IDA7CglzdGFjay5zdGF0ZXMgPSBjbGlfbWFsbG9jKHN0YWNrLnN0YWNrX3NpemUqc2l6ZW9mKCpzdGFjay5zdGF0ZXMpKTsKCglpZighc3RhY2suc3RhdGVzKQoJCXJldHVybiBDTF9FTUVNOwoKCWJ1ZmYgPSBjbGlfbWFsbG9jKEJVRkZfU0laRSk7CglpZighYnVmZikgewoJCWZyZWUoc3RhY2suc3RhdGVzKTsKCQlyZXR1cm4gQ0xfRU1FTTsKCX0KCgl0ZW1wbmFtZSA9IGNsaV9nZW50ZW1wKE5VTEwpOwoKCWlmKG1rZGlyKHRlbXBuYW1lLCAwNzAwKSkgewoJICAgIAljbGlfZGJnbXNnKCJTY2FuUlRGIC0+IENhbid0IGNyZWF0ZSB0ZW1wb3JhcnkgZGlyZWN0b3J5ICVzXG4iLCB0ZW1wbmFtZSk7CgkJZnJlZShzdGFjay5zdGF0ZXMpOwoJCWZyZWUoYnVmZik7CgkJZnJlZSh0ZW1wbmFtZSk7CgkJcmV0dXJuIENMX0VUTVBESVI7Cgl9CgoJYWN0aW9udGFibGUgPSB0YWJsZUNyZWF0ZSgpOwoJaWYoKHJldCA9IGxvYWRfYWN0aW9ucyhhY3Rpb250YWJsZSkpKSB7CgkJY2xpX2RiZ21zZygiUlRGOiBVbmFibGUgdG8gbG9hZCBydGYgYWN0aW9uIHRhYmxlXG4iKTsKCQlmcmVlKHN0YWNrLnN0YXRlcyk7CgkJZnJlZShidWZmKTsKCQlpZighY2xpX2xlYXZldGVtcHNfZmxhZykKCQkJY2xpX3JtZGlycyh0ZW1wbmFtZSk7CgkJZnJlZSh0ZW1wbmFtZSk7CgkJdGFibGVEZXN0cm95KGFjdGlvbnRhYmxlKTsKCQlyZXR1cm4gcmV0OwoJfQoKCWluaXRfcnRmX3N0YXRlKCZzdGF0ZSk7CgoJd2hpbGUoKCBicmVhZCA9IGNsaV9yZWFkbihkZXNjLCBidWZmLCBCVUZGX1NJWkUpICkgPiAwKSB7CgkJcHRyID0gYnVmZjsKCQlwdHJfZW5kID0gYnVmZiArIGJyZWFkOwoJCXdoaWxlKHB0ciA8IHB0cl9lbmQpIHsKCQkJc3dpdGNoKHN0YXRlLnBhcnNlX3N0YXRlKSB7CgkJCQljYXNlIFBBUlNFX01BSU46IAoJCQkJCXN3aXRjaCgqcHRyKyspIHsKCQkJCQkJY2FzZSAneyc6CgkJCQkJCQlpZigoIHJldCA9IHB1c2hfc3RhdGUoJnN0YWNrLCZzdGF0ZSkgKSkgewoJCQkJCQkJCWNsaV9kYmdtc2coIlJURjpQdXNoIGZhaWx1cmUhXG4iKTsKCQkJCQkJCQlTQ0FOX0NMRUFOVVA7CgkJCQkJCQkJcmV0dXJuIHJldDsKCQkJCQkJCX0KCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICd9JzoKCQkJCQkJCWlmKHN0YXRlLmNiX2RhdGEgJiYgc3RhdGUuY2JfZW5kKQoJCQkJCQkJCWlmKCggcmV0ID0gc3RhdGUuY2JfZW5kKCZzdGF0ZSwgY3R4KSApKSB7CgkJCQkJCQkJCVNDQU5fQ0xFQU5VUDsKCQkJCQkJCQkJcmV0dXJuIHJldDsKCQkJCQkJCQl9CgkJCQkJCQlpZigoIHJldCA9IHBvcF9zdGF0ZSgmc3RhY2ssJnN0YXRlKSApKSB7CgkJCQkJCQkJY2xpX2RiZ21zZygiUlRGOnBvcCBmYWlsdXJlIVxuIik7CgkJCQkJCQkJU0NBTl9DTEVBTlVQOwoJCQkJCQkJCXJldHVybiByZXQ7CgkJCQkJCQl9CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAnXFwnOgoJCQkJCQkJc3RhdGUucGFyc2Vfc3RhdGUgPSBQQVJTRV9DT05UUk9MXzsKCQkJCQkJCWJyZWFrOwoJCQkJCQlkZWZhdWx0OgoJCQkJCQkJcHRyLS07CgkJCQkJCQl7CgkJCQkJCQkJc2l6ZV90IGk7CgkJCQkJCQkJc2l6ZV90IGxlZnQgPSBwdHJfZW5kIC0gcHRyOwoJCQkJCQkJCXNpemVfdCB1c2UgPSBsZWZ0OwoJCQkJCQkJCWZvcihpID0gMTtpIDwgbGVmdDsgaSsrKQoJCQkJCQkJCQlpZihtYWluX3N5bWJvbHNbcHRyW2ldXSkgewoJCQkJCQkJCQkJdXNlID0gaTsKCQkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCQl9CgkJCQkJCQkJaWYoc3RhdGUuY2JfYmVnaW4pIHsKCQkJCQkJCQkJaWYoIXN0YXRlLmNiX2RhdGEpCgkJCQkJCQkJCQkgaWYoKCByZXQgPSBzdGF0ZS5jYl9iZWdpbigmc3RhdGUsIGN0eCx0ZW1wbmFtZSkgKSkgewoJCQkJCQkJCQkJCSBTQ0FOX0NMRUFOVVA7CgkJCQkJCQkJCQkJIHJldHVybiByZXQ7CgkJCQkJCQkJCQl9CgkJCQkJCQkJCWlmKCggcmV0ID0gc3RhdGUuY2JfcHJvY2Vzcygmc3RhdGUsIHB0ciwgdXNlKSApKSB7CgkJCQkJCQkJCQlpZihzdGF0ZS5jYl9lbmQpIHsKCQkJCQkJCQkJCQlzdGF0ZS5jYl9lbmQoJnN0YXRlLGN0eCk7CgkJCQkJCQkJCQl9CgkJCQkJCQkJCQlTQ0FOX0NMRUFOVVA7CgkJCQkJCQkJCQlyZXR1cm4gcmV0OwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJCXB0ciArPSB1c2U7CgkJCQkJCQl9CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSBQQVJTRV9DT05UUk9MXzoJCQkJCQoJCQkJCWlmKGlzYWxwaGEoKnB0cikpICB7CgkJCQkJCXN0YXRlLnBhcnNlX3N0YXRlID0gUEFSU0VfQ09OVFJPTF9XT1JEOwoJCQkJCQlzdGF0ZS5jb250cm9sd29yZF9jbnQgPSAwOwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJCXN0YXRlLnBhcnNlX3N0YXRlID0gUEFSU0VfQ09OVFJPTF9TWU1CT0w7CgkJCQkJYnJlYWs7CgkJCQljYXNlIFBBUlNFX0NPTlRST0xfU1lNQk9MOgoJCQkJCXB0cisrOwkvKiBEbyBub3RoaW5nICovCgkJCQkJc3RhdGUucGFyc2Vfc3RhdGUgPSBQQVJTRV9NQUlOOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBQQVJTRV9DT05UUk9MX1dPUkQ6CgkJCQkJaWYoc3RhdGUuY29udHJvbHdvcmRfY250ID09IDMyKSB7CgkJCQkJCWNsaV9kYmdtc2coIkludmFsaWQgY29udHJvbCB3b3JkOiBtYXhpbXVtIHNpemUgZXhjZWVkZWQ6JXNcbiIsc3RhdGUuY29udHJvbHdvcmQpOwoJCQkJCQlzdGF0ZS5wYXJzZV9zdGF0ZSA9IFBBUlNFX01BSU47CgkJCQkJfQoJCQkJCWVsc2UgaWYoaXNhbHBoYSgqcHRyKSkKCQkJCQkJc3RhdGUuY29udHJvbHdvcmRbc3RhdGUuY29udHJvbHdvcmRfY250KytdID0gKnB0cisrOwoJCQkJCWVsc2UgewoJCQkJCQlpZihpc3NwYWNlKCpwdHIpKSB7CgkJCQkJCQlzdGF0ZS5jb250cm9sd29yZFtzdGF0ZS5jb250cm9sd29yZF9jbnQrK10gPSAqcHRyKys7CgkJCQkJCQlzdGF0ZS5wYXJzZV9zdGF0ZSA9IFBBUlNFX0lOVEVSUFJFVF9DT05UUk9MV09SRDsKCQkJCQkJfQoJCQkJCQllbHNlIGlmIChpc2RpZ2l0KCpwdHIpKSB7CgkJCQkJCQlzdGF0ZS5wYXJzZV9zdGF0ZSA9IFBBUlNFX0NPTlRST0xfV09SRF9QQVJBTTsKCQkJCQkJCXN0YXRlLmNvbnRyb2x3b3JkX3BhcmFtID0gMDsKCQkJCQkJCXN0YXRlLmNvbnRyb2x3b3JkX3BhcmFtX3NpZ24gPSAxOwoJCQkJCQl9CgkJCQkJCWVsc2UgaWYoKnB0ciA9PSAnLScpIHsKCQkJCQkJCXB0cisrOwoJCQkJCQkJc3RhdGUucGFyc2Vfc3RhdGUgPSBQQVJTRV9DT05UUk9MX1dPUkRfUEFSQU07CgkJCQkJCQlzdGF0ZS5jb250cm9sd29yZF9wYXJhbSA9IDA7CgkJCQkJCQlzdGF0ZS5jb250cm9sd29yZF9wYXJhbV9zaWduID0gLTE7CgkJCQkJCX0KCQkJCQkJZWxzZSB7CgkJCQkJCQlzdGF0ZS5wYXJzZV9zdGF0ZSA9IFBBUlNFX0lOVEVSUFJFVF9DT05UUk9MV09SRDsKCQkJCQkJfQoJCQkJCX0KCQkJCQlicmVhazsKCQkJCWNhc2UgUEFSU0VfQ09OVFJPTF9XT1JEX1BBUkFNOgoJCQkJCWlmKGlzZGlnaXQoKnB0cikpIHsKCQkJCQkJc3RhdGUuY29udHJvbHdvcmRfcGFyYW0gPSBzdGF0ZS5jb250cm9sd29yZF9wYXJhbSoxMCArICpwdHIrKyAtICcwJzsKCQkJCQl9CgkJCQkJZWxzZSBpZihpc2FscGhhKCpwdHIpKSB7CgkJCQkJCXB0cisrOwoJCQkJCX0KCQkJCQllbHNlIHsKCQkJCQkJaWYoc3RhdGUuY29udHJvbHdvcmRfcGFyYW1fc2lnbiA8IDApCgkJCQkJCQlzdGF0ZS5jb250cm9sd29yZF9wYXJhbSA9IC1zdGF0ZS5jb250cm9sd29yZF9wYXJhbTsKCQkJCQkJc3RhdGUucGFyc2Vfc3RhdGUgPSBQQVJTRV9JTlRFUlBSRVRfQ09OVFJPTFdPUkQ7CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSBQQVJTRV9JTlRFUlBSRVRfQ09OVFJPTFdPUkQ6CgkJCQkJewoJCQkJCQlpbnQgYWN0aW9uOwoKCQkJCQkJc3RhdGUuY29udHJvbHdvcmRbc3RhdGUuY29udHJvbHdvcmRfY250XSA9ICdcMCc7CgkJCQkJCWFjdGlvbiA9IHRhYmxlRmluZChhY3Rpb250YWJsZSwgc3RhdGUuY29udHJvbHdvcmQpOwoJCQkJCQlpZihhY3Rpb24gIT0gLTEpIHsKCQkJCQkJCWlmKHN0YXRlLmNiX2RhdGEgJiYgc3RhdGUuY2JfZW5kKSB7LyogcHJlbWF0dXJlIGVuZCBvZiBwcmV2aW91cyBibG9jayAqLwoJCQkJCQkJCXN0YXRlLmNiX2VuZCgmc3RhdGUsY3R4KTsKCQkJCQkJCQlzdGF0ZS5jYl9iZWdpbiA9IE5VTEw7CgkJCQkJCQkJc3RhdGUuY2JfZW5kID0gTlVMTDsKCQkJCQkJCQlzdGF0ZS5jYl9kYXRhID0gTlVMTDsKCQkJCQkJCX0KCQkJCQkJCXJ0Zl9hY3Rpb24oJnN0YXRlLGFjdGlvbik7CgkJCQkJCX0KCQkJCQkJc3RhdGUucGFyc2Vfc3RhdGUgPSBQQVJTRV9NQUlOOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCX0KCQl9Cgl9CgoJU0NBTl9DTEVBTlVQOwoJcmV0dXJuIHJldDsKfQo=