LyoKICogQ29weXJpZ2h0IChDKSAyMDAzIE1pY2hhZWwgR/xubmV3aWcKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgQ09NX05PX1dJTkRPV1NfSAoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAibWVkaWFvYmouaCIKI2luY2x1ZGUgImRtb3J0LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobXNkbW8pOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICBNb0NyZWF0ZU1lZGlhVHlwZSAgICAoTVNETU8uQCkKICoKICogQWxsb2NhdGUgYSBuZXcgbWVkaWEgdHlwZSBzdHJ1Y3R1cmUKICovCkhSRVNVTFQgV0lOQVBJIE1vQ3JlYXRlTWVkaWFUeXBlKERNT19NRURJQV9UWVBFKiogcHBtZWRpYSwgRFdPUkQgY2JGb3JtYXQpCnsKICAgIEhSRVNVTFQgcjsKCiAgICBUUkFDRSgiJXAgJXVcbiIsIHBwbWVkaWEsIGNiRm9ybWF0KTsKCiAgICBpZiAoIXBwbWVkaWEpCiAgICAgICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgICAqcHBtZWRpYSA9IENvVGFza01lbUFsbG9jKHNpemVvZihETU9fTUVESUFfVFlQRSkpOwogICAgaWYgKCEqcHBtZWRpYSkKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICByID0gTW9Jbml0TWVkaWFUeXBlKCpwcG1lZGlhLCBjYkZvcm1hdCk7CiAgICBpZiAoRkFJTEVEKHIpKQogICAgewogICAgICAgIENvVGFza01lbUZyZWUoKnBwbWVkaWEpOwogICAgICAgICpwcG1lZGlhID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gcjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICBNb0luaXRNZWRpYVR5cGUgICAgICAgIChNU0RNTy5AKQogKgogKiBJbml0aWFsaXplIG1lZGlhIHR5cGUgc3RydWN0dXJlCiAqLwpIUkVTVUxUIFdJTkFQSSBNb0luaXRNZWRpYVR5cGUoRE1PX01FRElBX1RZUEUqIHBtZWRpYSwgRFdPUkQgY2JGb3JtYXQpCnsKICAgIFRSQUNFKCIlcCAldVxuIiwgcG1lZGlhLCBjYkZvcm1hdCk7CgogICAgaWYgKCFwbWVkaWEpCiAgICAgICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgICBtZW1zZXQocG1lZGlhLCAwLCBzaXplb2YoRE1PX01FRElBX1RZUEUpKTsKCiAgICBpZiAoY2JGb3JtYXQgPiAwKQogICAgewogICAgICAgIHBtZWRpYS0+cGJGb3JtYXQgPSBDb1Rhc2tNZW1BbGxvYyhjYkZvcm1hdCk7CiAgICAgICAgaWYgKCFwbWVkaWEtPnBiRm9ybWF0KQogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICAgICAgcG1lZGlhLT5jYkZvcm1hdCA9IGNiRm9ybWF0OwogICAgfQoKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgIE1vRGVsZXRlTWVkaWFUeXBlICAgIChNU0RNTy5AKQogKgogKiBEZWxldGUgYSBtZWRpYSB0eXBlIHN0cnVjdHVyZQogKi8KSFJFU1VMVCBXSU5BUEkgTW9EZWxldGVNZWRpYVR5cGUoRE1PX01FRElBX1RZUEUqIHBtZWRpYSkKewogICAgVFJBQ0UoIiVwXG4iLCBwbWVkaWEpOwoKICAgIGlmICghcG1lZGlhKQogICAgICAgIHJldHVybiBFX1BPSU5URVI7CgogICAgTW9GcmVlTWVkaWFUeXBlKHBtZWRpYSk7CiAgICBDb1Rhc2tNZW1GcmVlKHBtZWRpYSk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgTW9GcmVlTWVkaWFUeXBlICAgICAgICAoTVNETU8uQCkKICoKICogRnJlZSBhbGxvY2F0ZWQgbWVtYmVycyBvZiBhIG1lZGlhIHR5cGUgc3RydWN0dXJlCiAqLwpIUkVTVUxUIFdJTkFQSSBNb0ZyZWVNZWRpYVR5cGUoRE1PX01FRElBX1RZUEUqIHBtZWRpYSkKewogICAgVFJBQ0UoIiVwXG4iLCBwbWVkaWEpOwoKICAgIGlmICghcG1lZGlhKQogICAgICAgIHJldHVybiBFX1BPSU5URVI7CgogICAgaWYgKHBtZWRpYS0+cFVuaykKICAgIHsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKHBtZWRpYS0+cFVuayk7CiAgICAgICAgcG1lZGlhLT5wVW5rID0gTlVMTDsKICAgIH0KCiAgICBDb1Rhc2tNZW1GcmVlKHBtZWRpYS0+cGJGb3JtYXQpOwogICAgcG1lZGlhLT5wYkZvcm1hdCA9IE5VTEw7CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgTW9EdXBsaWNhdGVNZWRpYVR5cGUgICAgKE1TRE1PLkApCiAqCiAqIER1cGxpY2F0ZXMgYSBtZWRpYSB0eXBlIHN0cnVjdHVyZQogKi8KSFJFU1VMVCBXSU5BUEkgTW9EdXBsaWNhdGVNZWRpYVR5cGUoRE1PX01FRElBX1RZUEUqKiBwcGRzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRE1PX01FRElBX1RZUEUqIHBzcmMpCnsKICAgIEhSRVNVTFQgcjsKCiAgICBUUkFDRSgiJXAgJXBcbiIsIHBwZHN0LCBwc3JjKTsKCiAgICBpZiAoIXBwZHN0IHx8ICFwc3JjKQogICAgICAgIHJldHVybiBFX1BPSU5URVI7CgogICAgKnBwZHN0ID0gQ29UYXNrTWVtQWxsb2Moc2l6ZW9mKERNT19NRURJQV9UWVBFKSk7CiAgICBpZiAoISpwcGRzdCkKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICByID0gTW9Db3B5TWVkaWFUeXBlKCpwcGRzdCwgcHNyYyk7CiAgICBpZiAoRkFJTEVEKHIpKQogICAgewogICAgICAgIE1vRnJlZU1lZGlhVHlwZSgqcHBkc3QpOwogICAgICAgICpwcGRzdCA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgTW9Db3B5TWVkaWFUeXBlICAgICAgICAoTVNETU8uQCkKICoKICogQ29weSBhIG5ldyBtZWRpYSB0eXBlIHN0cnVjdHVyZQogKi8KSFJFU1VMVCBXSU5BUEkgTW9Db3B5TWVkaWFUeXBlKERNT19NRURJQV9UWVBFKiBwZHN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRE1PX01FRElBX1RZUEUqIHBzcmMpCnsKICAgIFRSQUNFKCIlcCAlcFxuIiwgcGRzdCwgcHNyYyk7CgogICAgaWYgKCFwZHN0IHx8ICFwc3JjKQogICAgICAgIHJldHVybiBFX1BPSU5URVI7CgogICAgbWVtY3B5KCZwZHN0LT5tYWpvcnR5cGUsICAmcHNyYy0+bWFqb3J0eXBlLCAgc2l6ZW9mKHBzcmMtPm1ham9ydHlwZSkpOwogICAgbWVtY3B5KCZwZHN0LT5zdWJ0eXBlLCAgICAmcHNyYy0+c3VidHlwZSwgICAgc2l6ZW9mKHBzcmMtPnN1YnR5cGUpKTsKICAgIG1lbWNweSgmcGRzdC0+Zm9ybWF0dHlwZSwgJnBzcmMtPmZvcm1hdHR5cGUsIHNpemVvZihwc3JjLT5mb3JtYXR0eXBlKSk7CgogICAgcGRzdC0+YkZpeGVkU2l6ZVNhbXBsZXMgICAgPSBwc3JjLT5iRml4ZWRTaXplU2FtcGxlczsKICAgIHBkc3QtPmJUZW1wb3JhbENvbXByZXNzaW9uID0gcHNyYy0+YlRlbXBvcmFsQ29tcHJlc3Npb247CiAgICBwZHN0LT5sU2FtcGxlU2l6ZSAgICAgICAgICA9IHBzcmMtPmxTYW1wbGVTaXplOwogICAgcGRzdC0+Y2JGb3JtYXQgICAgICAgICAgICAgPSBwc3JjLT5jYkZvcm1hdDsKCiAgICBpZiAocHNyYy0+cGJGb3JtYXQgJiYgcHNyYy0+Y2JGb3JtYXQgPiAwKQogICAgewogICAgICAgIHBkc3QtPnBiRm9ybWF0ID0gQ29UYXNrTWVtQWxsb2MocHNyYy0+Y2JGb3JtYXQpOwogICAgICAgIGlmICghcGRzdC0+cGJGb3JtYXQpCiAgICAgICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgICAgICBtZW1jcHkocGRzdC0+cGJGb3JtYXQsIHBzcmMtPnBiRm9ybWF0LCBwc3JjLT5jYkZvcm1hdCk7CiAgICB9CiAgICBlbHNlCiAgICAgICAgcGRzdC0+cGJGb3JtYXQgPSBOVUxMOwoKICAgIGlmIChwc3JjLT5wVW5rKQogICAgewogICAgICAgIHBkc3QtPnBVbmsgPSBwc3JjLT5wVW5rOwogICAgICAgIElVbmtub3duX0FkZFJlZihwZHN0LT5wVW5rKTsKICAgIH0KICAgIGVsc2UKICAgICAgICBwZHN0LT5wVW5rID0gTlVMTDsKCiAgICByZXR1cm4gU19PSzsKfQo=