LyoKICogQ29weXJpZ2h0IChDKSAyMDAzIE1pY2hhZWwgR/xubmV3aWcKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJtZWRpYW9iai5oIgojaW5jbHVkZSAiZG1vcnQuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChtc2Rtbyk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgIE1vQ3JlYXRlTWVkaWFUeXBlICAgIChNU0RNTy5AKQogKgogKiBBbGxvY2F0ZSBhIG5ldyBtZWRpYSB0eXBlIHN0cnVjdHVyZQogKi8KSFJFU1VMVCBXSU5BUEkgTW9DcmVhdGVNZWRpYVR5cGUoRE1PX01FRElBX1RZUEUqKiBwcG1lZGlhLCBEV09SRCBjYkZvcm1hdCkKewogICAgSFJFU1VMVCByOwoKICAgIFRSQUNFKCIlcCAldVxuIiwgcHBtZWRpYSwgY2JGb3JtYXQpOwoKICAgIGlmICghcHBtZWRpYSkKICAgICAgICByZXR1cm4gRV9QT0lOVEVSOwoKICAgICpwcG1lZGlhID0gQ29UYXNrTWVtQWxsb2Moc2l6ZW9mKERNT19NRURJQV9UWVBFKSk7CiAgICBpZiAoISpwcG1lZGlhKQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIHIgPSBNb0luaXRNZWRpYVR5cGUoKnBwbWVkaWEsIGNiRm9ybWF0KTsKICAgIGlmIChGQUlMRUQocikpCiAgICB7CiAgICAgICAgQ29UYXNrTWVtRnJlZSgqcHBtZWRpYSk7CiAgICAgICAgKnBwbWVkaWEgPSBOVUxMOwogICAgfQoKICAgIHJldHVybiByOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgIE1vSW5pdE1lZGlhVHlwZSAgICAgICAgKE1TRE1PLkApCiAqCiAqIEluaXRpYWxpemUgbWVkaWEgdHlwZSBzdHJ1Y3R1cmUKICovCkhSRVNVTFQgV0lOQVBJIE1vSW5pdE1lZGlhVHlwZShETU9fTUVESUFfVFlQRSogcG1lZGlhLCBEV09SRCBjYkZvcm1hdCkKewogICAgVFJBQ0UoIiVwICV1XG4iLCBwbWVkaWEsIGNiRm9ybWF0KTsKCiAgICBpZiAoIXBtZWRpYSkKICAgICAgICByZXR1cm4gRV9QT0lOVEVSOwoKICAgIG1lbXNldChwbWVkaWEsIDAsIHNpemVvZihETU9fTUVESUFfVFlQRSkpOwoKICAgIGlmIChjYkZvcm1hdCA+IDApCiAgICB7CiAgICAgICAgcG1lZGlhLT5wYkZvcm1hdCA9IENvVGFza01lbUFsbG9jKGNiRm9ybWF0KTsKICAgICAgICBpZiAoIXBtZWRpYS0+cGJGb3JtYXQpCiAgICAgICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgICAgICBwbWVkaWEtPmNiRm9ybWF0ID0gY2JGb3JtYXQ7CiAgICB9CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgTW9EZWxldGVNZWRpYVR5cGUgICAgKE1TRE1PLkApCiAqCiAqIERlbGV0ZSBhIG1lZGlhIHR5cGUgc3RydWN0dXJlCiAqLwpIUkVTVUxUIFdJTkFQSSBNb0RlbGV0ZU1lZGlhVHlwZShETU9fTUVESUFfVFlQRSogcG1lZGlhKQp7CiAgICBUUkFDRSgiJXBcbiIsIHBtZWRpYSk7CgogICAgaWYgKCFwbWVkaWEpCiAgICAgICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgICBNb0ZyZWVNZWRpYVR5cGUocG1lZGlhKTsKICAgIENvVGFza01lbUZyZWUocG1lZGlhKTsKCiAgICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICBNb0ZyZWVNZWRpYVR5cGUgICAgICAgIChNU0RNTy5AKQogKgogKiBGcmVlIGFsbG9jYXRlZCBtZW1iZXJzIG9mIGEgbWVkaWEgdHlwZSBzdHJ1Y3R1cmUKICovCkhSRVNVTFQgV0lOQVBJIE1vRnJlZU1lZGlhVHlwZShETU9fTUVESUFfVFlQRSogcG1lZGlhKQp7CiAgICBUUkFDRSgiJXBcbiIsIHBtZWRpYSk7CgogICAgaWYgKCFwbWVkaWEpCiAgICAgICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgICBpZiAocG1lZGlhLT5wVW5rKQogICAgewogICAgICAgIElVbmtub3duX1JlbGVhc2UocG1lZGlhLT5wVW5rKTsKICAgICAgICBwbWVkaWEtPnBVbmsgPSBOVUxMOwogICAgfQoKICAgIENvVGFza01lbUZyZWUocG1lZGlhLT5wYkZvcm1hdCk7CiAgICBwbWVkaWEtPnBiRm9ybWF0ID0gTlVMTDsKCiAgICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICBNb0R1cGxpY2F0ZU1lZGlhVHlwZSAgICAoTVNETU8uQCkKICoKICogRHVwbGljYXRlcyBhIG1lZGlhIHR5cGUgc3RydWN0dXJlCiAqLwpIUkVTVUxUIFdJTkFQSSBNb0R1cGxpY2F0ZU1lZGlhVHlwZShETU9fTUVESUFfVFlQRSoqIHBwZHN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBETU9fTUVESUFfVFlQRSogcHNyYykKewogICAgSFJFU1VMVCByOwoKICAgIFRSQUNFKCIlcCAlcFxuIiwgcHBkc3QsIHBzcmMpOwoKICAgIGlmICghcHBkc3QgfHwgIXBzcmMpCiAgICAgICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgICAqcHBkc3QgPSBDb1Rhc2tNZW1BbGxvYyhzaXplb2YoRE1PX01FRElBX1RZUEUpKTsKICAgIGlmICghKnBwZHN0KQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIHIgPSBNb0NvcHlNZWRpYVR5cGUoKnBwZHN0LCBwc3JjKTsKICAgIGlmIChGQUlMRUQocikpCiAgICB7CiAgICAgICAgTW9GcmVlTWVkaWFUeXBlKCpwcGRzdCk7CiAgICAgICAgKnBwZHN0ID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gcjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICBNb0NvcHlNZWRpYVR5cGUgICAgICAgIChNU0RNTy5AKQogKgogKiBDb3B5IGEgbmV3IG1lZGlhIHR5cGUgc3RydWN0dXJlCiAqLwpIUkVTVUxUIFdJTkFQSSBNb0NvcHlNZWRpYVR5cGUoRE1PX01FRElBX1RZUEUqIHBkc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBETU9fTUVESUFfVFlQRSogcHNyYykKewogICAgVFJBQ0UoIiVwICVwXG4iLCBwZHN0LCBwc3JjKTsKCiAgICBpZiAoIXBkc3QgfHwgIXBzcmMpCiAgICAgICAgcmV0dXJuIEVfUE9JTlRFUjsKCiAgICBwZHN0LT5tYWpvcnR5cGUgPSBwc3JjLT5tYWpvcnR5cGU7CiAgICBwZHN0LT5zdWJ0eXBlID0gcHNyYy0+c3VidHlwZTsKICAgIHBkc3QtPmZvcm1hdHR5cGUgPSBwc3JjLT5mb3JtYXR0eXBlOwoKICAgIHBkc3QtPmJGaXhlZFNpemVTYW1wbGVzICAgID0gcHNyYy0+YkZpeGVkU2l6ZVNhbXBsZXM7CiAgICBwZHN0LT5iVGVtcG9yYWxDb21wcmVzc2lvbiA9IHBzcmMtPmJUZW1wb3JhbENvbXByZXNzaW9uOwogICAgcGRzdC0+bFNhbXBsZVNpemUgICAgICAgICAgPSBwc3JjLT5sU2FtcGxlU2l6ZTsKICAgIHBkc3QtPmNiRm9ybWF0ICAgICAgICAgICAgID0gcHNyYy0+Y2JGb3JtYXQ7CgogICAgaWYgKHBzcmMtPnBiRm9ybWF0ICYmIHBzcmMtPmNiRm9ybWF0ID4gMCkKICAgIHsKICAgICAgICBwZHN0LT5wYkZvcm1hdCA9IENvVGFza01lbUFsbG9jKHBzcmMtPmNiRm9ybWF0KTsKICAgICAgICBpZiAoIXBkc3QtPnBiRm9ybWF0KQogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICAgICAgbWVtY3B5KHBkc3QtPnBiRm9ybWF0LCBwc3JjLT5wYkZvcm1hdCwgcHNyYy0+Y2JGb3JtYXQpOwogICAgfQogICAgZWxzZQogICAgICAgIHBkc3QtPnBiRm9ybWF0ID0gTlVMTDsKCiAgICBpZiAocHNyYy0+cFVuaykKICAgIHsKICAgICAgICBwZHN0LT5wVW5rID0gcHNyYy0+cFVuazsKICAgICAgICBJVW5rbm93bl9BZGRSZWYocGRzdC0+cFVuayk7CiAgICB9CiAgICBlbHNlCiAgICAgICAgcGRzdC0+cFVuayA9IE5VTEw7CgogICAgcmV0dXJuIFNfT0s7Cn0K