LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgSEVYVE9VTklfSAojZGVmaW5lIEhFWFRPVU5JX0gKCiNpbmNsdWRlICJ1bmljb2RlL3RyYW5zbGl0LmgiCgovKioKICogQSB0cmFuc2xpdGVyYXRvciB0aGF0IGNvbnZlcnRzIGZyb20gaGV4YWRlY2ltYWwgVW5pY29kZSBlc2NhcGUKICogc2VxdWVuY2VzIHRvIHRoZSBjaGFyYWN0ZXJzIHRoZXkgcmVwcmVzZW50LiAgRm9yIGV4YW1wbGUsICJVKzAwNDAiCiAqIGFuZCAnXHUwMDQwJy4gIEEgZGVmYXVsdCBIZXhUb1VuaWNvZGVUcmFuc2xpdGVyYXRvciByZWNvZ25pemVzIHRoZQogKiBwcmVmaXhlcyAiVSsiLCAidSsiLCAiJiM5MjtVIiwgYW5kICImIzkyO3UiLiAgSGV4IHZhbHVlcyBtYXkgYmUKICogdXBwZXItIG9yIGxvd2VyY2FzZS4gIEJ5IGNhbGxpbmcgdGhlIGFwcGx5UGF0dGVybigpIG1ldGhvZCwgb25lCiAqIG9yIG1vcmUgY3VzdG9tIHByZWZpeC9zdWZmaXggcGFpcnMgbWF5IGJlIHNwZWNpZmllZC4gIFNlZQogKiBhcHBseVBhdHRlcm4oKSBmb3IgZGV0YWlscy4KICoKICogPHA+Q29weXJpZ2h0ICZjb3B5OyBJQk0gQ29ycG9yYXRpb24gMTk5OS4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIEBhdXRob3IgQWxhbiBMaXUKICogQHZlcnNpb24gJFJDU2ZpbGU6IGhleHRvdW5pLmgsdiAkICRSZXZpc2lvbjogMS43ICQgJERhdGU6IDIwMDAvMDYvMjcgMTk6MDA6MzggJAogKiBAZHJhZnQKICovCmNsYXNzIFVfSTE4Tl9BUEkgSGV4VG9Vbmljb2RlVHJhbnNsaXRlcmF0b3IgOiBwdWJsaWMgVHJhbnNsaXRlcmF0b3IgewoKICAgIC8qKgogICAgICogSUQgZm9yIHRoaXMgdHJhbnNsaXRlcmF0b3IuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBjaGFyKiBfSUQ7CgogICAgLyoqCiAgICAgKiBUaGUgcGF0dGVybiB1c2VkIGJ5IHRoZSBkZWZhdWx0IGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBVbmljb2RlU3RyaW5nIERFRkFVTFRfUEFUVEVSTjsKCiAgICAvLyBDaGFyYWN0ZXIgY29uc3RhbnRzIGRlZmluZWQgaGVyZSB0byBhdm9pZCBBU0NJSSBkZXBlbmRlbmN5CiAgICBlbnVtIHsKICAgICAgICBTRU1JQ09MT04gPSAweDAwM0IsIC8vICc7JwogICAgICAgIFpFUk8gICAgICA9IDB4MDAzMCwgLy8gJzAnCiAgICAgICAgUE9VTkQgICAgID0gMHgwMDIzLCAvLyAnIycKICAgICAgICBCQUNLU0xBU0ggPSAweDAwNUMgIC8vICdcXCcKICAgIH07CgogICAgLyoqCiAgICAgKiBUaGUgcGF0dGVybiBmb3IgdGhpcyB0cmFuc2xpdGVyYXRvcgogICAgICovCiAgICBVbmljb2RlU3RyaW5nIHBhdHRlcm47CgogICAgLyoqCiAgICAgKiBUaGUgcHJvY2Vzc2VkIHBhdHRlcm4gc3BlY2lmaWNhdGlvbi4gIFNlZSBhcHBseVBhdHRlcm4oKSBmb3IKICAgICAqIGRldGFpbHMuCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcgYWZmaXhlczsKCiAgICAvKioKICAgICAqIFRoZSBudW1iZXIgb2YgZGlmZmVyZW50IGFmZml4IHNldHMgaW4gYWZmaXhlcy4KICAgICAqLwogICAgaW50MzJfdCBhZmZpeENvdW50OwoKcHVibGljOgoKICAgIC8qKgogICAgICogQ29uc3RydWN0cyBhIHRyYW5zbGl0ZXJhdG9yIHRoYXQgcmVjb2duaXplcyB0aGUgc3RhbmRhcmQKICAgICAqIHByZWZpeGVzICImIzkyO3UiLCAiJiM5MjtVIiwgInUrIiwgYW5kICJVKyIsIGVhY2ggd2l0aCBubwogICAgICogc3VmZml4LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIEhleFRvVW5pY29kZVRyYW5zbGl0ZXJhdG9yKFVuaWNvZGVGaWx0ZXIqIGFkb3B0ZWRGaWx0ZXIgPSAwKTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdHMgYSBjdXN0b20gdHJhbnNsaXRlcmF0b3Igd2l0aCB0aGUgZ2l2ZW4gcGF0dGVybi4KICAgICAqIEBzZWUgI2FwcGx5UGF0dGVybgogICAgICovCiAgICBIZXhUb1VuaWNvZGVUcmFuc2xpdGVyYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdHMgYSBjdXN0b20gdHJhbnNsaXRlcmF0b3Igd2l0aCB0aGUgZ2l2ZW4gcGF0dGVybgogICAgICogYW5kIGZpbHRlci4KICAgICAqIEBzZWUgI2FwcGx5UGF0dGVybgogICAgICovCiAgICBIZXhUb1VuaWNvZGVUcmFuc2xpdGVyYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZUZpbHRlciogYWRvcHRlZEZpbHRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgfkhleFRvVW5pY29kZVRyYW5zbGl0ZXJhdG9yKCk7CgogICAgLyoqCiAgICAgKiBDb3B5IGNvbnN0cnVjdG9yLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIEhleFRvVW5pY29kZVRyYW5zbGl0ZXJhdG9yKGNvbnN0IEhleFRvVW5pY29kZVRyYW5zbGl0ZXJhdG9yJik7CgogICAgLyoqCiAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9yLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIEhleFRvVW5pY29kZVRyYW5zbGl0ZXJhdG9yJiBvcGVyYXRvcj0oY29uc3QgSGV4VG9Vbmljb2RlVHJhbnNsaXRlcmF0b3ImKTsKCiAgICAvKioKICAgICAqIFRyYW5zbGl0ZXJhdG9yIEFQSS4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBUcmFuc2xpdGVyYXRvciogY2xvbmUodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHBhdHRlcm5zIHJlY29nbml6ZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIE9uZSBvcgogICAgICogbW9yZSBwYXR0ZXJucyBtYXkgYmUgc3BlY2lmaWVkLCBzZXBhcmF0ZWQgYnkgc2VtaWNvbG9ucyAoJzsnKS4KICAgICAqIEVhY2ggcGF0dGVybiBjb250YWlucyB6ZXJvIG9yIG1vcmUgcHJlZml4IGNoYXJhY3RlcnMsIG9uZSBvcgogICAgICogbW9yZSBkaWdpdCBjaGFyYWN0ZXJzLCBhbmQgemVybyBvciBtb3JlIHN1ZmZpeCBjaGFyYWN0ZXJzLiAgVGhlCiAgICAgKiBkaWdpdCBjaGFyYWN0ZXJzIGluZGljYXRlcyBvcHRpb25hbCBkaWdpdHMgKCcjJykgZm9sbG93ZWQgYnkKICAgICAqIHJlcXVpcmVkIGRpZ2l0cyAoJzAnKS4gIFRoZSB0b3RhbCBudW1iZXIgb2YgZGlnaXRzIGNhbm5vdAogICAgICogZXhjZWVkIDQsIGFuZCBtdXN0IGJlIGF0IGxlYXN0IDEgcmVxdWlyZWQgZGlnaXQuICBVc2UgYQogICAgICogYmFja3NsYXNoICgnXFwnKSB0byBlc2NhcGUgYW55IG9mIHRoZSBzcGVjaWFsIGNoYXJhY3RlcnMuICBBbgogICAgICogZW1wdHkgcGF0dGVybiBpcyBhbGxvd2VkOyBpdCBzcGVjaWZpZXMgYSB0cmFuc2xpdGVyYXRvciB0aGF0CiAgICAgKiBkb2VzIG5vdGhpbmcuCiAgICAgKgogICAgICogPHA+RXhhbXBsZTogIlUrMDAwMDs8IyMjMD4iIHNwZWNpZmllcyB0d28gcGF0dGVybnMuICBUaGUgZmlyc3QKICAgICAqIGhhcyBhIHByZWZpeCBvZiAiVSsiLCBleGFjdGx5IGZvdXIgZGlnaXRzLCBhbmQgbm8gc3VmZml4LiAgVGhlCiAgICAgKiBzZWNvbmQgaGFzIGEgcHJlZml4IG9mICI8IiwgYmV0d2VlbiBvbmUgYW5kIGZvdXIgZGlnaXRzLCBhbmQgYQogICAgICogc3VmZml4IG9mICI+Ii4KICAgICAqCiAgICAgKiA8cD48cHJlPgogICAgICogcGF0dGVybiA6PSBzcGVjIHwgKCBwYXR0ZXJuICc7JyBzcGVjICkKICAgICAqIHNwZWMgOj0gcHJlZml4LWNoYXIqIGRpZ2l0LXNwZWMgc3VmZml4LWNoYXIqCiAgICAgKiBkaWdpdC1zcGVjIDo9ICcjJyogJzAnKwogICAgICogcHJlZml4LWNoYXIgOj0gW15zcGVjaWFsLWNoYXJdIHwgJ1xcJyBzcGVjaWFsLWNoYXIKICAgICAqIHN1ZmZpeC1jaGFyIDo9IFtec3BlY2lhbC1jaGFyXSB8ICdcXCcgc3BlY2lhbC1jaGFyCiAgICAgKiBzcGVjaWFsLWNoYXIgOj0gJzsnIHwgJzAnIHwgJyMnIHwgJ1xcJwogICAgICogPC9wcmU+CiAgICAgKi8KICAgIHZvaWQgYXBwbHlQYXR0ZXJuKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRoZVBhdHRlcm4sIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhpcyB0cmFuc2xpdGVyYXRvcidzIHBhdHRlcm4uCiAgICAgKi8KICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRvUGF0dGVybih2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIEltcGxlbWVudHMge0BsaW5rIFRyYW5zbGl0ZXJhdG9yI2hhbmRsZVRyYW5zbGl0ZXJhdGV9LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBoYW5kbGVUcmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlJiB0ZXh0LCBVVHJhbnNQb3NpdGlvbiYgb2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUJvb2wgaXNJbmNyZW1lbnRhbCkgY29uc3Q7Cn07CgppbmxpbmUgSGV4VG9Vbmljb2RlVHJhbnNsaXRlcmF0b3I6On5IZXhUb1VuaWNvZGVUcmFuc2xpdGVyYXRvcigpIHt9CgojZW5kaWYK