LyoqCiAqIEBmaWxlIHByb2ZpbGUuaAogKiBFbmNhcHN1bGF0aW9uIGZvciBzYW1wbGVzIGZpbGVzIG92ZXIgYWxsIHByb2ZpbGUgY2xhc3NlcwogKiBiZWxvbmdpbmcgdG8gdGhlIHNhbWUgYmluYXJ5IGltYWdlCiAqCiAqIEByZW1hcmsgQ29weXJpZ2h0IDIwMDIgT1Byb2ZpbGUgYXV0aG9ycwogKiBAcmVtYXJrIFJlYWQgdGhlIGZpbGUgQ09QWUlORwogKgogKiBAYXV0aG9yIFBoaWxpcHBlIEVsaWUKICogQGF1dGhvciBKb2huIExldm9uCiAqLwoKI2lmbmRlZiBQUk9GSUxFX0gKI2RlZmluZSBQUk9GSUxFX0gKCiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDxtYXA+CiNpbmNsdWRlIDxpdGVyYXRvcj4KCiNpbmNsdWRlICJvZGIuaCIKI2luY2x1ZGUgIm9wX3R5cGVzLmgiCiNpbmNsdWRlICJ1dGlsaXR5LmgiCiNpbmNsdWRlICJwb3B1bGF0ZV9mb3Jfc3B1LmgiCgpjbGFzcyBvcGRfaGVhZGVyOwpjbGFzcyBvcF9iZmQ7CgovKioKICogQ2xhc3MgY29udGFpbmluZyBhIHNpbmdsZSBzYW1wbGUgZmlsZSBjb250ZW50cy4KICogaS5lLiBzZXQgb2YgY291bnQgdmFsdWVzIGZvciBWTUEgb2Zmc2V0cyBmb3IKICogYSBwYXJ0aWN1bGFyIGJpbmFyeS4KICovCmNsYXNzIHByb2ZpbGVfdCA6IG5vbmNvcHlhYmxlIHsKcHVibGljOgoJLyoqCgkgKiBwcm9maWxlX3QgLSBjb25zdHJ1Y3QgYW4gZW1wdHkgIHByb2ZpbGVfdCBvYmplY3QKCSAqLwoJcHJvZmlsZV90KCk7CgoJLy8vIHJldHVybiB0cnVlIGlmIG5vIHNhbXBsZSBmaWxlIGhhcyBiZWVuIGxvYWRlZAoJYm9vbCBlbXB0eSgpIGNvbnN0IHsgcmV0dXJuICFmaWxlX2hlYWRlci5nZXQoKTsgfQogCgkvLy8gcmV0dXJuIHRoZSBoZWFkZXIgb2YgdGhlIGxhc3Qgb3BlbmVkIHNhbXBsZXMgZmlsZQoJb3BkX2hlYWRlciBjb25zdCAmIGdldF9oZWFkZXIoKSBjb25zdCB7CgkJcmV0dXJuICpmaWxlX2hlYWRlcjsKCX0KCgkvKioKCSAqIGNvdW50IHNhbXBsZXMgY291bnQgdy9vIHJlY29yZGluZyB0aGVtCgkgKiBAcGFyYW0gZmlsZW5hbWUgc2FtcGxlIGZpbGVuYW1lCgkgKgoJICogY29udmVuaWVuY2UgaW50ZXJmYWNlIGZvciByYXcgYWNjZXNzIHRvIHNhbXBsZSBjb3VudCB3L28gcmVjb3JkaW5nCgkgKiB0aGVtLiBJdCdzIHBsYWNlZCBoZXJlIHNvIGFsbCBhY2Nlc3MgdG8gc2FtcGxlcyBmaWxlcyBnbyB0aHJvdWdoCgkgKiBwcm9maWxlX3Qgc3RhdGljIG9yIG5vbiBzdGF0aWMgbWVtYmVyLgoJICovCglzdGF0aWMgY291bnRfdHlwZSBzYW1wbGVfY291bnQoc3RkOjpzdHJpbmcgY29uc3QgJiBmaWxlbmFtZSk7CgoJLyoqCgkgKiBJbmRpY2F0ZSBpZiBnaXZlbiBzYW1wbGUgZmlsZSBpcyBmcm9tIGEgQ2VsbCBCcm9hZGJhbmQgRW5naW5lCgkgKiBTUFUgcHJvZmlsZQoJICogQHBhcmFtIGZpbGVuYW1lIHNhbXBsZSBmaWxlbmFtZQoJICoKCSAqIENvbnZlbmllbmNlIGludGVyZmFjZSBwdXQgaGVyZSBzbyBhbGwgYWNjZXNzIHRvIHNhbXBsZXMgZmlsZXMKCSAqIGdvIHRocm91Z2ggcHJvZmlsZV90IHN0YXRpYyBvciBub24gc3RhdGljIG1lbWJlci4KCSAqLwoJc3RhdGljIGVudW0gcHJvZmlsZV90eXBlIGlzX3NwdV9zYW1wbGVfZmlsZShzdGQ6OnN0cmluZyBjb25zdCAmIGZpbGVuYW1lKTsKCgkvKioKCSAqIGN1bXVsYXRlIHNhbXBsZSBmaWxlIHRvIG91ciBjb250YWluZXIgb2Ygc2FtcGxlcwoJICogQHBhcmFtIGZpbGVuYW1lICBzYW1wbGUgZmlsZSBuYW1lCgkgKgoJICogc3RvcmUgc2FtcGxlcyBmb3Igb25lIHNhbXBsZSBmaWxlLCBzYW1wbGUgZmlsZSBoZWFkZXIgaXMgc2FuaXRpemVkLgoJICoKCSAqIGFsbCBlcnJvciBhcmUgZmF0YWwKCSAqLwoJdm9pZCBhZGRfc2FtcGxlX2ZpbGUoc3RkOjpzdHJpbmcgY29uc3QgJiBmaWxlbmFtZSk7CgoJLy8vIFNldCBhbiBhcHByb3ByaWF0ZSBzdGFydCBvZmZzZXQsIHNlZSBjb21tZW50cyBiZWxvdy4KCXZvaWQgc2V0X29mZnNldChvcF9iZmQgY29uc3QgJiBhYmZkKTsKCgljbGFzcyBjb25zdF9pdGVyYXRvcjsKCXR5cGVkZWYgc3RkOjpwYWlyPGNvbnN0X2l0ZXJhdG9yLCBjb25zdF9pdGVyYXRvcj4gaXRlcmF0b3JfcGFpcjsKCgkvKioKCSAqIEBwYXJhbSBzdGFydCAgc3RhcnQgb2Zmc2V0CgkgKiBAcGFyYW0gZW5kICBlbmQgb2Zmc2V0CgkgKgoJICogcmV0dXJuIGFuIGl0ZXJhdG9yIHBhaXIgdG8gW3N0YXJ0LCBlbmQpIHJhbmdlCgkgKi8KCWl0ZXJhdG9yX3BhaXIKCXNhbXBsZXNfcmFuZ2Uob2RiX2tleV90IHN0YXJ0LCBvZGJfa2V5X3QgZW5kKSBjb25zdDsKCgkvLy8gcmV0dXJuIGEgcGFpciBvZiBpdGVyYXRvciBmb3IgYWxsIHNhbXBsZXMKCWl0ZXJhdG9yX3BhaXIgc2FtcGxlc19yYW5nZSgpIGNvbnN0OwoKcHJpdmF0ZToKCS8vLyBoZWxwZXIgZm9yIHNhbXBsZV9jb3VudCgpIGFuZCBhZGRfc2FtcGxlX2ZpbGUoKS4gQWxsIGVycm9yIGxhdW5jaAoJLy8vIGFuIGV4Y2VwdGlvbi4KCXN0YXRpYyB2b2lkCglvcGVuX3NhbXBsZV9maWxlKHN0ZDo6c3RyaW5nIGNvbnN0ICYgZmlsZW5hbWUsIG9kYl90ICYpOwoKCS8vLyBjb3B5IG9mIHRoZSBzYW1wbGVzIGZpbGUgaGVhZGVyCglzY29wZWRfcHRyPG9wZF9oZWFkZXI+IGZpbGVfaGVhZGVyOwoKCS8vLyBzdG9yYWdlIHR5cGUgZm9yIHNhbXBsZXMgc29ydGVkIGJ5IGVpcAoJdHlwZWRlZiBzdGQ6Om1hcDxvZGJfa2V5X3QsIGNvdW50X3R5cGU+IG9yZGVyZWRfc2FtcGxlc190OwoKCS8qKgoJICogU2FtcGxlcyBhcmUgc3RvcmVkIGluIGhhc2ggdGFibGUsIGl0ZXJhdGluZyBvdmVyIGhhc2ggdGFibGUgZG9uJ3QKCSAqIHByb3ZpZGUgYW55IG9yZGVyaW5nLCB0aGUgYWJvdmUgY291bnQoKSBpbnRlcmZhY2UgcmVseSBvbiBzYW1wbGVzCgkgKiBvcmRlcmVkIGJ5IGVpcC4gVGhpcyBtYXAgaXMgb25seSBhIHRlbXBvcmFyeSBzdG9yYWdlIHdoZXJlIHNhbXBsZXMKCSAqIGFyZSBvcmRlcmVkIGJ5IGVpcC4KCSAqLwoJb3JkZXJlZF9zYW1wbGVzX3Qgb3JkZXJlZF9zYW1wbGVzOwoKCS8qKgoJICogRm9yIGNlcnRhaW4gcHJvZmlsZXMsIHN1Y2ggYXMga2VybmVsL21vZHVsZXMsIGFuZCBhbm9uCgkgKiByZWdpb25zIHdpdGggYSBtYXRjaGluZyBiaW5hcnksIHRoaXMgdmFsdWUgaXMgbm9uLXplcm8sCgkgKiBhbmQgcmVwcmVzZW50cyB0aGUgZmlsZSBvZmZzZXQgb2YgdGhlIHJlbGV2YW50IHNlY3Rpb24uCgkgKgoJICogRm9yIGtlcm5lbCBwcm9maWxlcywgdGhpcyBpcyBkb25lIGJlY2F1c2Ugd2UgdXNlIHRoZSBpbmZvcm1hdGlvbgoJICogcHJvdmlkZWQgaW4gL3Byb2Mva3N5bXMsIHdoaWNoIG9ubHkgZ2l2ZXMgdGhlIG1hcHBlZCBwb3NpdGlvbiBvZgoJICogLnRleHQsIGFuZCB0aGUgc3ltYm9sIF90ZXh0IGZyb20gdm1saW51eC4gVGhpcyB2YWx1ZSBpcyB1c2VkIHRvIGZpeAoJICogdXAgdGhlIHNhbXBsZSBvZmZzZXRzIGZvciBrZXJuZWwgY29kZSBhcyBhIHJlc3VsdCBvZiB0aGlzIGRpZmZlcmVuY2UKCSAqCgkgKiBJbiB1c2VyLXNwYWNlIHNhbXBsZXMsIHRoZSBzYW1wbGUgb2Zmc2V0IGlzIGZyb20gdGhlIHN0YXJ0IG9mIHRoZQoJICogbWFwcGVkIGZpbGUsIGFzIHNlZW4gaW4gL3Byb2MvcGlkL21hcHMuIFRoaXMgaXMgZmluZSBmb3IKCSAqIG1hcHBpbmdzIG9mIHBlcm1hbmVudCBmaWxlcywgYnV0IHdpdGggYW5vbiBtYXBwaW5ncywgd2UgbmVlZAoJICogdG8gYWRqdXN0IHRoZSBrZXkgdmFsdWVzIHRvIGJlIGEgZmlsZSBvZmZzZXQgYWdhaW5zdCB0aGUKCSAqICpiaW5hcnkqIChpZiB0aGVyZSBpcyBvbmUpLiBUaGlzIGNhbiBvYnZpb3VzbHkgYmUgZGlmZmVyZW50LgoJICogU28gd2UgcGFzcyBvdXIgYW5vbiBtYXBwaW5nIHN0YXJ0IFZNQSB0byBvcF9iZmQsIHdoaWNoIGxvb2tzCgkgKiBmb3IgYSBzZWN0aW9uIHdpdGggdGhhdCBWTUEsIHRoZW4gcmV0dXJucyB0aGUgc2VjdGlvbidzCgkgKiBmaWxlcG9zLiBTbyBhbGwgaXMgZ29vZC4KCSAqCgkgKiBGaW5hbGx5LCBub3RlIHRoYXQgZm9yIGNnIHdlIGNhbid0IHVzZSB0aGlzIGluc2lkZSB0aGUKCSAqIHByb2ZpbGVfdCwgYXMgd2UncmUgc3RvcmluZyB0d28gb2Zmc2V0cyBpbiB0aGUga2V5IHZhbHVlLiBTbwoJICogd2UgZG8gaXQgbGF0ZXIgaW4gdGhhdCBjYXNlLgoJICoKCSAqIFBoZXcuCgkgKi8KCXU2NCBzdGFydF9vZmZzZXQ7Cn07CgoKLy8gSXQgd2lsbCBiZSBlYXNpZXIgdG8gZGVyaXZlIHByb2ZpbGVfdDo6Y29uc3RfaXRlcmF0b3IgZnJvbQovLyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6aW5wdXRfaXRlcmF0b3JfdGFnLCB1bnNpZ25lZCBpbnQ+IGJ1dCB0aGlzIGRvZXNuJ3QKLy8gd29yayBmb3IgZ2NjIDw9IDIuOTUgc28gd2UgcHJvdmlkZSB0aGUgbmVjY2Vzc2FyeSB0eXBlZGVmIGluIHRoZSBoYXJkIHdheS4KLy8gU2VlIElTTyBDKysgMTcuNC4zLjEgpyAxIGFuZCAxNC43LjMgpyA5LgpuYW1lc3BhY2Ugc3RkIHsKCXRlbXBsYXRlIDw+CgkJc3RydWN0IGl0ZXJhdG9yX3RyYWl0czxwcm9maWxlX3Q6OmNvbnN0X2l0ZXJhdG9yPiB7CgkJCXR5cGVkZWYgcHRyZGlmZl90IGRpZmZlcmVuY2VfdHlwZTsKCQkJdHlwZWRlZiBjb3VudF90eXBlIHZhbHVlX3R5cGU7CgkJCXR5cGVkZWYgY291bnRfdHlwZSAqIHBvaW50ZXI7CgkJCXR5cGVkZWYgY291bnRfdHlwZSAmIHJlZmVyZW5jZTsKCQkJdHlwZWRlZiBpbnB1dF9pdGVyYXRvcl90YWcgaXRlcmF0b3JfY2F0ZWdvcnk7CgkJfTsKfQoKCmNsYXNzIHByb2ZpbGVfdDo6Y29uc3RfaXRlcmF0b3IKewoJdHlwZWRlZiBvcmRlcmVkX3NhbXBsZXNfdDo6Y29uc3RfaXRlcmF0b3IgaXRlcmF0b3JfdDsKcHVibGljOgoJY29uc3RfaXRlcmF0b3IoKSA6IHN0YXJ0X29mZnNldCgwKSB7fQoJY29uc3RfaXRlcmF0b3IoaXRlcmF0b3JfdCBpdF8sIHU2NCBzdGFydF9vZmZzZXRfKQoJCTogaXQoaXRfKSwgc3RhcnRfb2Zmc2V0KHN0YXJ0X29mZnNldF8pIHt9CgoJY291bnRfdHlwZSBvcGVyYXRvciooKSBjb25zdCB7IHJldHVybiBpdC0+c2Vjb25kOyB9Cgljb25zdF9pdGVyYXRvciAmIG9wZXJhdG9yKysoKSB7ICsraXQ7IHJldHVybiAqdGhpczsgfQoKCW9kYl9rZXlfdCB2bWEoKSBjb25zdCB7IHJldHVybiBpdC0+Zmlyc3QgKyBzdGFydF9vZmZzZXQ7IH0KCWNvdW50X3R5cGUgY291bnQoKSBjb25zdCB7IHJldHVybiAqKnRoaXM7IH0KCglib29sIG9wZXJhdG9yIT0oY29uc3RfaXRlcmF0b3IgY29uc3QgJiByaHMpIGNvbnN0IHsKCQlyZXR1cm4gaXQgIT0gcmhzLml0OwoJfQoJYm9vbCBvcGVyYXRvcj09KGNvbnN0X2l0ZXJhdG9yIGNvbnN0ICYgcmhzKSBjb25zdCB7CgkJcmV0dXJuIGl0ID09IHJocy5pdDsKCX0KCnByaXZhdGU6CglpdGVyYXRvcl90IGl0OwoJdTY0IHN0YXJ0X29mZnNldDsKfTsKCiNlbmRpZiAvKiAhUFJPRklMRV9IICovCg==