LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgUkJUX1NFVF9ICiNkZWZpbmUgUkJUX1NFVF9ICgojaW5jbHVkZSAidXZlY3Rvci5oIgoKY2xhc3MgUmVwbGFjZWFibGU7CmNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGU7CmNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhOwpjbGFzcyBVbmljb2RlRmlsdGVyOwpjbGFzcyBVbmljb2RlU3RyaW5nOwoKLyoqCiAqIEEgc2V0IG9mIHJ1bGVzIGZvciBhIDxjb2RlPlJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yPC9jb2RlPi4gIFRoaXMgc2V0IGVuY29kZXMKICogdGhlIHRyYW5zbGl0ZXJhdGlvbiBpbiBvbmUgZGlyZWN0aW9uIGZyb20gb25lIHNldCBvZiBjaGFyYWN0ZXJzIG9yIHNob3J0CiAqIHN0cmluZ3MgdG8gYW5vdGhlci4gIEEgPGNvZGU+UnVsZUJhc2VkVHJhbnNsaXRlcmF0b3I8L2NvZGU+IGNvbnNpc3RzIG9mIHVwIHRvCiAqIHR3byBzdWNoIHNldHMsIG9uZSBmb3IgdGhlIGZvcndhcmQgZGlyZWN0aW9uLCBhbmQgb25lIGZvciB0aGUgcmV2ZXJzZS4KICoKICogPHA+QSA8Y29kZT5UcmFuc2xpdGVyYXRpb25SdWxlU2V0PC9jb2RlPiBoYXMgb25lIGltcG9ydGFudCBvcGVyYXRpb24sIHRoYXQgb2YKICogZmluZGluZyBhIG1hdGNoaW5nIHJ1bGUgYXQgYSBnaXZlbiBwb2ludCBpbiB0aGUgdGV4dC4gIFRoaXMgaXMgYWNjb21wbGlzaGVkCiAqIGJ5IHRoZSA8Y29kZT5maW5kTWF0Y2goKTwvY29kZT4gbWV0aG9kLgogKgogKiBAYXV0aG9yIEFsYW4gTGl1CiAqLwpjbGFzcyBUcmFuc2xpdGVyYXRpb25SdWxlU2V0IHsKICAgIC8qKgogICAgICogVmVjdG9yIG9mIHJ1bGVzLCBpbiB0aGUgb3JkZXIgYWRkZWQuICBUaGlzIGlzIG9ubHkgdXNlZCB3aGlsZSB0aGUgcnVsZQogICAgICogc2V0IGlzIGdldHRpbmcgYnVpbHQuICBBZnRlciB0aGF0LCBmcmVlemUoKSByZW9yZGVycyBhbmQgaW5kZXhlcyB0aGUKICAgICAqIHJ1bGVzLCBhbmQgdGhpcyBWZWN0b3IgaXMgZnJlZWQuCiAgICAgKi8KICAgIFVWZWN0b3IqIHJ1bGVWZWN0b3I7CgogICAgLyoqCiAgICAgKiBMZW5ndGggb2YgdGhlIGxvbmdlc3QgcHJlY2VkaW5nIGNvbnRleHQKICAgICAqLwogICAgaW50MzJfdCBtYXhDb250ZXh0TGVuZ3RoOwoKICAgIC8qKgogICAgICogU29ydGVkIGFuZCBpbmRleGVkIHRhYmxlIG9mIHJ1bGVzLiAgVGhpcyBpcyBjcmVhdGVkIGJ5IGZyZWV6ZSgpIGZyb20KICAgICAqIHRoZSBydWxlcyBpbiBydWxlVmVjdG9yLgogICAgICovCiAgICBUcmFuc2xpdGVyYXRpb25SdWxlKiogcnVsZXM7CgogICAgLyoqCiAgICAgKiBJbmRleCB0YWJsZS4gIEZvciB0ZXh0IGhhdmluZyBhIGZpcnN0IGNoYXJhY3RlciBjLCBjb21wdXRlIHggPSBjJjB4RkYuCiAgICAgKiBOb3cgdXNlIHJ1bGVzW2luZGV4W3hdLi5pbmRleFt4KzFdLTFdLiAgVGhpcyBpbmRleCB0YWJsZSBpcyBjcmVhdGVkIGJ5CiAgICAgKiBmcmVlemUoKS4KICAgICAqLwogICAgaW50MzJfdCBpbmRleFsyNTddOwoKcHVibGljOgoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgbmV3IGVtcHR5IHJ1bGUgc2V0LgogICAgICovCiAgICBUcmFuc2xpdGVyYXRpb25SdWxlU2V0KCk7CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yLgogICAgICovCiAgICB2aXJ0dWFsIH5UcmFuc2xpdGVyYXRpb25SdWxlU2V0KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIG1heGltdW0gY29udGV4dCBsZW5ndGguCiAgICAgKiBAcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGxvbmdlc3QgcHJlY2VkaW5nIGNvbnRleHQuCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBnZXRNYXhpbXVtQ29udGV4dExlbmd0aCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIEFkZCBhIHJ1bGUgdG8gdGhpcyBzZXQuICBSdWxlcyBhcmUgYWRkZWQgaW4gb3JkZXIsIGFuZCBvcmRlciBpcwogICAgICogc2lnbmlmaWNhbnQuCiAgICAgKgogICAgICogPHA+T25jZSBmcmVlemUoKSBpcyBjYWxsZWQsIHRoaXMgbWV0aG9kIG11c3Qgbm90IGJlIGNhbGxlZC4KICAgICAqIEBwYXJhbSBhZG9wdGVkUnVsZSB0aGUgcnVsZSB0byBhZGQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGFkZFJ1bGUoVHJhbnNsaXRlcmF0aW9uUnVsZSogYWRvcHRlZFJ1bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ2xvc2UgdGhpcyBydWxlIHNldCB0byBmdXJ0aGVyIGFkZGl0aW9ucywgY2hlY2sgaXQgZm9yIG1hc2tlZCBydWxlcywKICAgICAqIGFuZCBpbmRleCBpdCB0byBvcHRpbWl6ZSBwZXJmb3JtYW5jZS4gIE9uY2UgdGhpcyBtZXRob2QgaXMgY2FsbGVkLAogICAgICogYWRkUnVsZSgpIGNhbiBubyBsb25nZXIgYmUgY2FsbGVkLgogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc29tZSBydWxlcyBhcmUgbWFza2VkCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBmcmVlemUoY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBBdHRlbXB0IHRvIGZpbmQgYSBtYXRjaGluZyBydWxlIGF0IHRoZSBzcGVjaWZpZWQgcG9pbnQgaW4gdGhlIHRleHQuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGV4dCwgYm90aCB0cmFuc2xhdGVkIGFuZCB1bnRyYW5zbGF0ZWQKICAgICAqIEBwYXJhbSBzdGFydCB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmU7IDxjb2RlPjAgPD0gc3RhcnQKICAgICAqIDw9IGxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmU7IDxjb2RlPnN0YXJ0IDw9IGxpbWl0CiAgICAgKiA8PSB0ZXh0Lmxlbmd0aCgpPC9jb2RlPi4KICAgICAqIEBwYXJhbSBjdXJzb3IgcG9zaXRpb24gYXQgd2hpY2ggdG8gdHJhbnNsYXRlIG5leHQsIHJlcHJlc2VudGluZyBvZmZzZXQKICAgICAqIGludG8gdGV4dC4gIFRoaXMgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDxjb2RlPnN0YXJ0PC9jb2RlPiBhbmQKICAgICAqIDxjb2RlPmxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBkYXRhIGEgZGljdGlvbmFyeSBtYXBwaW5nIHZhcmlhYmxlcyB0byB0aGUgc2V0cyB0aGV5CiAgICAgKiByZXByZXNlbnQgKG1hcHMgPGNvZGU+Q2hhcmFjdGVyPC9jb2RlPiB0byA8Y29kZT5Vbmljb2RlU2V0PC9jb2RlPikKICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmlzSW4oKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICogQHJldHVybiB0aGUgbWF0Y2hpbmcgcnVsZSwgb3IgbnVsbCBpZiBub25lIGZvdW5kLgogICAgICovCiAgICB2aXJ0dWFsIFRyYW5zbGl0ZXJhdGlvblJ1bGUqIGZpbmRNYXRjaChjb25zdCBSZXBsYWNlYWJsZSYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc3RhcnQsIGludDMyX3QgbGltaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGN1cnNvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZUZpbHRlciogZmlsdGVyKSBjb25zdDsKICAgIAogICAgLyoqCiAgICAgKiBBdHRlbXB0IHRvIGZpbmQgYSBtYXRjaGluZyBydWxlIGF0IHRoZSBzcGVjaWZpZWQgcG9pbnQgaW4gdGhlIHRleHQuCiAgICAgKiBVbmxpa2UgPGNvZGU+ZmluZE1hdGNoKCk8L2NvZGU+LCB0aGlzIG1ldGhvZCBkb2VzIGFuIGluY3JlbWVudGFsIG1hdGNoLgogICAgICogQW4gaW5jcmVtZW50YWwgbWF0Y2ggcmVxdWlyZXMgdGhhdCB0aGVyZSBiZSBubyBwYXJ0aWFsIG1hdGNoZXMgdGhhdCBtaWdodAogICAgICogcHJlLWVtcHQgdGhlIGZ1bGwgbWF0Y2ggdGhhdCBpcyBmb3VuZC4gIElmIHRoZXJlIGFyZSBwYXJ0aWFsIG1hdGNoZXMsCiAgICAgKiB0aGVuIG51bGwgaXMgcmV0dXJuZWQuICBBIG5vbi1udWxsIHJlc3VsdCBpbmRpY2F0ZXMgdGhhdCBhIGZ1bGwgbWF0Y2ggaGFzCiAgICAgKiBiZWVuIGZvdW5kLCBhbmQgdGhhdCBpdCBjYW5ub3QgYmUgcHJlLWVtcHRlZCBieSBhIHBhcnRpYWwgbWF0Y2gKICAgICAqIHJlZ2FyZGxlc3Mgb2Ygd2hhdCBhZGRpdGlvbmFsIHRleHQgaXMgYWRkZWQgdG8gdGhlIHRyYW5zbGF0aW9uIGJ1ZmZlci4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0LCBib3RoIHRyYW5zbGF0ZWQgYW5kIHVudHJhbnNsYXRlZAogICAgICogQHBhcmFtIHN0YXJ0IHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZTsgPGNvZGU+MCA8PSBzdGFydAogICAgICogPD0gbGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGxpbWl0IHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZTsgPGNvZGU+c3RhcnQgPD0gbGltaXQKICAgICAqIDw9IHRleHQubGVuZ3RoKCk8L2NvZGU+LgogICAgICogQHBhcmFtIGN1cnNvciBwb3NpdGlvbiBhdCB3aGljaCB0byB0cmFuc2xhdGUgbmV4dCwgcmVwcmVzZW50aW5nIG9mZnNldAogICAgICogaW50byB0ZXh0LiAgVGhpcyB2YWx1ZSBtdXN0IGJlIGJldHdlZW4gPGNvZGU+c3RhcnQ8L2NvZGU+IGFuZAogICAgICogPGNvZGU+bGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGRhdGEgYSBkaWN0aW9uYXJ5IG1hcHBpbmcgdmFyaWFibGVzIHRvIHRoZSBzZXRzIHRoZXkKICAgICAqIHJlcHJlc2VudCAobWFwcyA8Y29kZT5DaGFyYWN0ZXI8L2NvZGU+IHRvIDxjb2RlPlVuaWNvZGVTZXQ8L2NvZGU+KQogICAgICogQHBhcmFtIHBhcnRpYWwgb3V0cHV0IHBhcmFtZXRlci4gIDxjb2RlPnBhcnRpYWxbMF08L2NvZGU+IGlzIHNldCB0bwogICAgICogdHJ1ZSBpZiBhIHBhcnRpYWwgbWF0Y2ggaXMgcmV0dXJuZWQuCiAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5pc0luKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqIEByZXR1cm4gdGhlIG1hdGNoaW5nIHJ1bGUsIG9yIG51bGwgaWYgbm9uZSBmb3VuZCwgb3IgaWYgdGhlIHRleHQgYnVmZmVyCiAgICAgKiBkb2VzIG5vdCBoYXZlIGVub3VnaCB0ZXh0IHlldCB0byB1bmFtYmlndW91c2x5IG1hdGNoIGEgcnVsZS4KICAgICAqLwogICAgdmlydHVhbCBUcmFuc2xpdGVyYXRpb25SdWxlKiBmaW5kSW5jcmVtZW50YWxNYXRjaChjb25zdCBSZXBsYWNlYWJsZSYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxpbWl0LCBpbnQzMl90IGN1cnNvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbF90JiBpc1BhcnRpYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlRmlsdGVyKiBmaWx0ZXIpIGNvbnN0Owp9OwojZW5kaWYK