LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgUkJUX1BBUlNfSAojZGVmaW5lIFJCVF9QQVJTX0gKCiNpbmNsdWRlICJ1bmljb2RlL3JidC5oIgoKY2xhc3MgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGE7CmNsYXNzIFVuaWNvZGVTZXQ7CgpjbGFzcyBUcmFuc2xpdGVyYXRpb25SdWxlUGFyc2VyIHsKCiAgICAvKioKICAgICAqIFRoaXMgaXMgYSByZWZlcmVuY2UgdG8gZXh0ZXJuYWwgZGF0YSB3ZSBkb24ndCBvd24uICBUaGlzIHdvcmtzIGJlY2F1c2UKICAgICAqIHdlIG9ubHkgaG9sZCB0aGlzIGZvciB0aGUgZHVyYXRpb24gb2YgdGhlIGNhbGwgdG8gcGFyc2UoKS4KICAgICAqLwogICAgY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXM7CgogICAgUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3I6OkRpcmVjdGlvbiBkaXJlY3Rpb247CgogICAgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEqIGRhdGE7CgogICAgLyoqCiAgICAgKiBXZSB1c2UgYSBzaW5nbGUgZXJyb3IgY29kZSBkdXJpbmcgcGFyc2luZy4gIFJhdGhlciB0aGFuIHBhc3MgaXQKICAgICAqIHRocm91Z2ggZWFjaCBBUEksIHdlIGtlZXAgaXQgaGVyZS4KICAgICAqLwogICAgVUVycm9yQ29kZSBzdGF0dXM7CgogICAgLyoqCiAgICAgKiBUaGUgbmV4dCBhdmFpbGFibGUgc3RhbmQtaW4gZm9yIHZhcmlhYmxlcy4gIFRoaXMgc3RhcnRzIGF0IHNvbWUgcG9pbnQgaW4KICAgICAqIHRoZSBwcml2YXRlIHVzZSBhcmVhIChkaXNjb3ZlcmVkIGR5bmFtaWNhbGx5KSBhbmQgaW5jcmVtZW50cyB1cCB0b3dhcmQKICAgICAqIDxjb2RlPnZhcmlhYmxlTGltaXQ8L2NvZGU+LiAgQXQgYW55IHBvaW50IGR1cmluZyBwYXJzaW5nLCBhdmFpbGFibGUKICAgICAqIHZhcmlhYmxlcyBhcmUgPGNvZGU+dmFyaWFibGVOZXh0Li52YXJpYWJsZUxpbWl0LTE8L2NvZGU+LgogICAgICovCiAgICBVQ2hhciB2YXJpYWJsZU5leHQ7CgogICAgLyoqCiAgICAgKiBUaGUgbGFzdCBhdmFpbGFibGUgc3RhbmQtaW4gZm9yIHZhcmlhYmxlcy4gIFRoaXMgaXMgZGlzY292ZXJlZAogICAgICogZHluYW1pY2FsbHkuICBBdCBhbnkgcG9pbnQgZHVyaW5nIHBhcnNpbmcsIGF2YWlsYWJsZSB2YXJpYWJsZXMgYXJlCiAgICAgKiA8Y29kZT52YXJpYWJsZU5leHQuLnZhcmlhYmxlTGltaXQtMTwvY29kZT4uCiAgICAgKi8KICAgIFVDaGFyIHZhcmlhYmxlTGltaXQ7CgogICAgLy8gT3BlcmF0b3JzCiAgICBzdGF0aWMgY29uc3QgVUNoYXIgVkFSSUFCTEVfREVGX09QOwogICAgc3RhdGljIGNvbnN0IFVDaGFyIEZPUldBUkRfUlVMRV9PUDsKICAgIHN0YXRpYyBjb25zdCBVQ2hhciBSRVZFUlNFX1JVTEVfT1A7CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgRldEUkVWX1JVTEVfT1A7IC8vIGludGVybmFsIHJlcCBvZiA8PiBvcAogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgT1BFUkFUT1JTOwoKICAgIC8vIE90aGVyIHNwZWNpYWwgY2hhcmFjdGVycwogICAgc3RhdGljIGNvbnN0IFVDaGFyIFFVT1RFOwogICAgc3RhdGljIGNvbnN0IFVDaGFyIEVTQ0FQRTsKICAgIHN0YXRpYyBjb25zdCBVQ2hhciBFTkRfT0ZfUlVMRTsKICAgIHN0YXRpYyBjb25zdCBVQ2hhciBSVUxFX0NPTU1FTlRfQ0hBUjsKICAgIHN0YXRpYyBjb25zdCBVQ2hhciBWQVJJQUJMRV9SRUZfT1BFTjsKICAgIHN0YXRpYyBjb25zdCBVQ2hhciBWQVJJQUJMRV9SRUZfQ0xPU0U7CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgQ09OVEVYVF9PUEVOOwogICAgc3RhdGljIGNvbnN0IFVDaGFyIENPTlRFWFRfQ0xPU0U7CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgU0VUX09QRU47CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgU0VUX0NMT1NFOwogICAgc3RhdGljIGNvbnN0IFVDaGFyIENVUlNPUl9QT1M7CgpwdWJsaWM6CgogICAgc3RhdGljIFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhKgogICAgICAgIHBhcnNlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgIFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yOjpEaXJlY3Rpb24gZGlyZWN0aW9uKTsKICAgIApwcml2YXRlOgoKICAgIC8qKgogICAgICogQHBhcmFtIHJ1bGVzIGxpc3Qgb2YgcnVsZXMsIHNlcGFyYXRlZCBieSBuZXdsaW5lIGNoYXJhY3RlcnMKICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgc3ludGF4IGVycm9yIGluIHRoZQogICAgICogcnVsZXMKICAgICAqLwogICAgVHJhbnNsaXRlcmF0aW9uUnVsZVBhcnNlcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3I6OkRpcmVjdGlvbiBkaXJlY3Rpb24pOwoKICAgIC8qKgogICAgICogUGFyc2UgdGhlIGdpdmVuIHN0cmluZyBhcyBhIHNlcXVlbmNlIG9mIHJ1bGVzLCBzZXBhcmF0ZWQgYnkgbmV3bGluZQogICAgICogY2hhcmFjdGVycyAoJ1xuJyksIGFuZCBjYXVzZSB0aGlzIG9iamVjdCB0byBpbXBsZW1lbnQgdGhvc2UgcnVsZXMuICBBbnkKICAgICAqIHByZXZpb3VzIHJ1bGVzIGFyZSBkaXNjYXJkZWQuICBUeXBpY2FsbHkgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGV4YWN0bHkKICAgICAqIG9uY2UsIGR1cmluZyBjb25zdHJ1Y3Rpb24uCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHN5bnRheCBlcnJvciBpbiB0aGUKICAgICAqIHJ1bGVzCiAgICAgKi8KICAgIHZvaWQgcGFyc2VSdWxlcyh2b2lkKTsKCiAgICAvKioKICAgICAqIE1BSU4gUEFSU0VSLiAgUGFyc2UgdGhlIG5leHQgcnVsZSBpbiB0aGUgZ2l2ZW4gcnVsZSBzdHJpbmcsIHN0YXJ0aW5nCiAgICAgKiBhdCBwb3MuICBSZXR1cm4gdGhlIGluZGV4IGFmdGVyIHRoZSBsYXN0IGNoYXJhY3RlciBwYXJzZWQuICBEbyBub3QKICAgICAqIHBhcnNlIGNoYXJhY3RlcnMgYXQgb3IgYWZ0ZXIgbGltaXQuCiAgICAgKgogICAgICogSW1wb3J0YW50OiAgVGhlIGNoYXJhY3RlciBhdCBwb3MgbXVzdCBiZSBhIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcgogICAgICogdGhhdCBpcyBub3QgdGhlIGNvbW1lbnQgY2hhcmFjdGVyLgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIGhhbmRsZXMgcXVvdGluZywgZXNjYXBpbmcsIGFuZCB3aGl0ZXNwYWNlIHJlbW92YWwuICBJdAogICAgICogcGFyc2VzIHRoZSBlbmQtb2YtcnVsZSBjaGFyYWN0ZXIuICBJdCByZWNvZ25pemVzIGNvbnRleHQgYW5kIGN1cnNvcgogICAgICogaW5kaWNhdG9ycy4gIE9uY2UgaXQgZG9lcyBhIGxleGljYWwgYnJlYWtkb3duIG9mIHRoZSBydWxlIGF0IHBvcywgaXQKICAgICAqIGNyZWF0ZXMgYSBydWxlIG9iamVjdCBhbmQgYWRkcyBpdCB0byBvdXIgcnVsZSBsaXN0LgogICAgICovCiAgICBpbnQzMl90IHBhcnNlUnVsZShpbnQzMl90IHBvcywgaW50MzJfdCBsaW1pdCk7CgogICAgLyoqCiAgICAgKiBDYWxsZWQgYnkgbWFpbiBwYXJzZXIgdXBvbiBzeW50YXggZXJyb3IuICBTZWFyY2ggdGhlIHJ1bGUgc3RyaW5nCiAgICAgKiBmb3IgdGhlIHByb2JhYmxlIGVuZCBvZiB0aGUgcnVsZS4gIE9mIGNvdXJzZSwgaWYgdGhlIGVycm9yIGlzIHRoYXQKICAgICAqIHRoZSBlbmQgb2YgcnVsZSBtYXJrZXIgaXMgbWlzc2luZywgdGhlbiB0aGUgcnVsZSBlbmQgd2lsbCBub3QgYmUgZm91bmQuCiAgICAgKiBJbiBhbnkgY2FzZSB0aGUgcnVsZSBzdGFydCB3aWxsIGJlIGNvcnJlY3RseSByZXBvcnRlZC4KICAgICAqIEBwYXJhbSBtc2cgZXJyb3IgZGVzY3JpcHRpb24KICAgICAqIEBwYXJhbSBydWxlIHBhdHRlcm4gc3RyaW5nCiAgICAgKiBAcGFyYW0gc3RhcnQgcG9zaXRpb24gb2YgZmlyc3QgY2hhcmFjdGVyIG9mIGN1cnJlbnQgcnVsZQogICAgICovCiAgICBpbnQzMl90IHN5bnRheEVycm9yKGNvbnN0IGNoYXIqIG1zZywgY29uc3QgVW5pY29kZVN0cmluZyYsIGludDMyX3Qgc3RhcnQpOwoKICAgIC8qKgogICAgICogQWxsb2NhdGUgYSBwcml2YXRlLXVzZSBzdWJzdGl0dXRpb24gY2hhcmFjdGVyIGZvciB0aGUgZ2l2ZW4gc2V0LAogICAgICogcmVnaXN0ZXIgaXQgaW4gdGhlIHNldFZhcmlhYmxlcyBoYXNoLCBhbmQgcmV0dXJuIHRoZSBzdWJzdGl0dXRpb24KICAgICAqIGNoYXJhY3Rlci4KICAgICAqLwogICAgVUNoYXIgcmVnaXN0ZXJTZXQoVW5pY29kZVNldCogYWRvcHRlZFNldCk7CiAKICAgIC8qKgogICAgICogRGV0ZXJtaW5lcyB3aGF0IHBhcnQgb2YgdGhlIHByaXZhdGUgdXNlIHJlZ2lvbiBvZiBVbmljb2RlIHdlIGNhbiB1c2UgZm9yCiAgICAgKiB2YXJpYWJsZSBzdGFuZC1pbnMuICBUaGUgY29ycmVjdCB3YXkgdG8gZG8gdGhpcyBpcyBhcyBmb2xsb3dzOiBQYXJzZSBlYWNoCiAgICAgKiBydWxlLCBhbmQgZm9yIGZvcndhcmQgYW5kIHJldmVyc2UgcnVsZXMsIHRha2UgdGhlIEZST00gZXhwcmVzc2lvbiwgYW5kCiAgICAgKiBtYWtlIGEgaGFzaCBvZiBhbGwgY2hhcmFjdGVycyB1c2VkLiAgVGhlIFRPIGV4cHJlc3Npb24gc2hvdWxkIGJlIGlnbm9yZWQuCiAgICAgKiBXaGVuIGRvbmUsIGV2ZXJ5dGhpbmcgbm90IGluIHRoZSBoYXNoIGlzIGF2YWlsYWJsZSBmb3IgdXNlLiAgSW4gcHJhY3RpY2UsCiAgICAgKiB0aGlzIG1ldGhvZCBtYXkgZW1wbG95IHNvbWUgb3RoZXIgYWxnb3JpdGhtIGZvciBpbXByb3ZlZCBzcGVlZC4KICAgICAqLwogICAgdm9pZCBkZXRlcm1pbmVWYXJpYWJsZVJhbmdlKHZvaWQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiBhIHNldCwgaWdub3JpbmcgcXVvdGVkIHRleHQuCiAgICAgKiBGb3IgZXhhbXBsZSwgaW4gdGhlIHN0cmluZyAiYWJjJ2hpZGUnaCIsIHRoZSAnaCcgaW4gImhpZGUiIHdpbGwgbm90IGJlCiAgICAgKiBmb3VuZCBieSBhIHNlYXJjaCBmb3IgImgiLiAgVW5saWtlIFN0cmluZy5pbmRleE9mKCksIHRoaXMgbWV0aG9kIHNlYXJjaGVzCiAgICAgKiBub3QgZm9yIGEgc2luZ2xlIGNoYXJhY3RlciwgYnV0IGZvciBhbnkgY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcKICAgICAqIDxjb2RlPnNldE9mQ2hhcnM8L2NvZGU+LgogICAgICogQHBhcmFtIHRleHQgdGV4dCB0byBiZSBzZWFyY2hlZAogICAgICogQHBhcmFtIHN0YXJ0IHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZTsgPGNvZGU+MCA8PSBzdGFydAogICAgICogPD0gbGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGxpbWl0IHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZTsgPGNvZGU+c3RhcnQgPD0gbGltaXQKICAgICAqIDw9IHRleHQubGVuZ3RoKCk8L2NvZGU+LgogICAgICogQHBhcmFtIHNldE9mQ2hhcnMgc3RyaW5nIHdpdGggb25lIG9yIG1vcmUgZGlzdGluY3QgY2hhcmFjdGVycwogICAgICogQHJldHVybiBPZmZzZXQgb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiA8Y29kZT5zZXRPZkNoYXJzPC9jb2RlPgogICAgICogZm91bmQsIG9yIC0xIGlmIG5vdCBmb3VuZC4KICAgICAqIEBzZWUgI2luZGV4T2YKICAgICAqLwogICAgc3RhdGljIGludDMyX3QgcXVvdGVkSW5kZXhPZihjb25zdCBVbmljb2RlU3RyaW5nJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHN0YXJ0LCBpbnQzMl90IGxpbWl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBzZXRPZkNoYXJzKTsKfTsKCiNlbmRpZgo=