LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogQ29weXJpZ2h0IChDKSB7MTk5Ni0yMDAxfSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCi8qKgoqIEZpbGUgdGJsY29sbC5jcHAKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqICAyLzUvOTcgICAgICBhbGl1ICAgICAgICBBZGRlZCBzdHJlYW1JbiBhbmQgc3RyZWFtT3V0IG1ldGhvZHMuICBBZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciB3aGljaCByZWFkcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbQoqICAgICAgICAgICAgICAgICAgICAgICAgICBhIGJpbmFyeSBmaWxlLiAgQWRkZWQgd3JpdGVUb0ZpbGUgbWV0aG9kIHdoaWNoIHN0cmVhbXMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3Igb3V0IHRvIGEgYmluYXJ5IGZpbGUuICBUaGUgc3RyZWFtSW4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIHN0cmVhbU91dCBtZXRob2RzIHVzZSBpc3RyZWFtIGFuZCBvc3RyZWFtIG9iamVjdHMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gYmluYXJ5IG1vZGUuCiogIDIvMTEvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIGRlY2xhcmF0aW9ucyBvdXQgb2YgZm9yIGxvb3AgaW5pdGlhbGl6ZXIuCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIE1hYyBjb21wYXRpYmlsaXR5ICNpZmRlZiBmb3IgaW9zOjpub2NyZWF0ZS4KKiAgMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gdXNlIFRhYmxlQ29sbGF0aW9uRGF0YSBzdWItb2JqZWN0IHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGQgaW52YXJpYW50IGRhdGEuCiogIDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBpbnRvIHRoaXMgY2xhc3MgZnJvbSBDb2xsYXRpb24uCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIGEgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKSBjb25zdHJ1Y3RvciwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgdXNlZCBieSBDb2xsYXRvcjo6Z2V0SW5zdGFuY2UoKS4gIEdlbmVyYWwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW4gdXAuICBNYWRlIHVzZSBvZiBVRXJyb3JDb2RlIHZhcmlhYmxlcyBjb25zaXN0ZW50LgoqICAyLzIwLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjbG9uZSwgb3BlcmF0b3I9PSwgb3BlcmF0b3IhPSwgb3BlcmF0b3I9LCBhbmQgY29weQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBhbmQgZ2V0RHluYW1pY0NsYXNzSUQuCiogIDMvNS85NyAgICAgIGFsaXUgICAgICAgIENoYW5nZWQgY29tcGFjdGlvbiBjeWNsZSB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLiAgV2UKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlIHRoZSBtYXhpbXVtIGFsbG93YWJsZSB2YWx1ZSB3aGljaCBpcyBrQmxvY2tDb3VudC4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgTW9kaWZpZWQgZ2V0UnVsZXMoKSB0byBsb2FkIHJ1bGVzIGR5bmFtaWNhbGx5LiAgQ2hhbmdlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RGcm9tRmlsZSgpIGNhbGwgdG8gYWNjb21vZGF0ZSB0aGlzIChhZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgdG8gc3BlY2lmeSB3aGV0aGVyIGJpbmFyeSBsb2FkaW5nIGlzIHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UgcGxhY2UpLgoqIDA1LzA2Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBtZW1vcnkgYWxsb2NhdGlvbiBlcnJvciBjaGVjay4KKiAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KKiAgNi8yMy85NyAgICAgaGVsZW5hICAgICAgQWRkaW5nIGNvbW1lbnRzIHRvIG1ha2UgY29kZSBtb3JlIHJlYWRhYmxlLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwNi8yNi85OCAgICAgZXJtICAgICAgICAgQ2hhbmdlcyBmb3IgQ29sbGF0aW9uS2V5cyB1c2luZyBieXRlIGFycmF5cy4KKiAwOC8xMC85OCAgICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIG9mIFJ1bGVCYXNlZENvbGxhdG9yLmphdmEKKiAwNC8yMy85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBFRGVjb21wb3NpdGlvbk1vZGUsIG1lcmdlZCB3aXRoCiogICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlCiogMDYvMTQvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQga1Jlc291cmNlQnVuZGxlU3VmZml4CiogMDYvMjIvOTkgICAgIHN0ZXBoZW4gICAgIEZpeGVkIGxvZ2ljIGluIGNvbnN0cnVjdEZyb21GaWxlKCkgc2luY2UgLmN0eAoqICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlcyBhcmUgbm8gbG9uZ2VyIHVzZWQuCiogMTEvMDIvOTkgICAgIGhlbGVuYSAgICAgIENvbGxhdG9yIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50cy4gIFNwZWNpYWwgY2FzZQoqICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgTk9fT1Agc2l0dWF0aW9ucy4KKiAxMS8xNy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluZWQgc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMuCiogMTIvMTUvOTkgICAgIGFsaXUgICAgICAgIFVwZGF0ZSB0byBzdXBwb3J0IFRoYWkgY29sbGF0aW9uLiAgTW92ZSBOb3JtYWxpemVySXRlcmF0b3IKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gaW1wbGVtZW50YXRpb24gZmlsZS4KKiAwMS8yOS8wMSAgICAgc3lud2VlICAgICAgTW9kaWZpZWQgaW50byBhIEMrKyB3cmFwcGVyIGNhbGxpbmcgQyBBUElzICh1Y29sLmgpCiovCgojaW5jbHVkZSAidW5pY29kZS90Ymxjb2xsLmgiCiNpbmNsdWRlICJ1bmljb2RlL2NvbGVpdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvcmVzYnVuZC5oIgojaW5jbHVkZSAidWNvbF9pbXAuaCIKI2luY2x1ZGUgInVyZXNpbXAuaCIKI2luY2x1ZGUgInVoYXNoLmgiCiNpbmNsdWRlICJjbWVtb3J5LmgiCgovKiBwdWJsaWMgUnVsZUJhc2VkQ29sbGF0b3IgY29uc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKVV9OQU1FU1BBQ0VfQkVHSU4KCi8qKgoqIENvcHkgY29uc3RydWN0b3IKKi8KUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0KSA6CiAgICAgICAgICAgICAgQ29sbGF0b3IodGhhdCksIGRhdGFJc093bmVkKEZBTFNFKSwgdWNvbGxhdG9yKHRoYXQudWNvbGxhdG9yKSwKICAgICAgICAgICAgICB1cnVsZXN0cmluZyh0aGF0LnVydWxlc3RyaW5nKQp7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIFVDT0xfREVGQVVMVF9TVFJFTkdUSCwKICAgICAgICAgICAgVUNPTF9ERUZBVUxULAogICAgICAgICAgICBzdGF0dXMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDogZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIGdldFVDb2xsYXRpb25TdHJlbmd0aChjb2xsYXRpb25TdHJlbmd0aCksCiAgICAgICAgICAgIFVDT0xfREVGQVVMVCwKICAgICAgICAgICAgc3RhdHVzKTsKfQoKLy8gVE9ETyB0aGlzIGlzIGEgZGVwcmVjYXRlZCBjb25zdHJ1Y3RvciwgcmVtb3ZlID4yMDAyLXNlcC0zMApSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIFVDT0xfREVGQVVMVF9TVFJFTkdUSCwKICAgICAgICAgICAgKFVDb2xBdHRyaWJ1dGVWYWx1ZSlOb3JtYWxpemVyOjpnZXRVTm9ybWFsaXphdGlvbk1vZGUoZGVjb21wb3NpdGlvbk1vZGUsIHN0YXR1cyksCiAgICAgICAgICAgIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDb2xBdHRyaWJ1dGVWYWx1ZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIFVDT0xfREVGQVVMVF9TVFJFTkdUSCwKICAgICAgICAgICAgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgIHN0YXR1cyk7Cn0KCi8vIFRPRE8gdGhpcyBpcyBhIGRlcHJlY2F0ZWQgY29uc3RydWN0b3IsIHJlbW92ZSA+MjAwMi1zZXAtMzAKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDogZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIGdldFVDb2xsYXRpb25TdHJlbmd0aChjb2xsYXRpb25TdHJlbmd0aCksCiAgICAgICAgICAgIChVQ29sQXR0cmlidXRlVmFsdWUpTm9ybWFsaXplcjo6Z2V0VU5vcm1hbGl6YXRpb25Nb2RlKGRlY29tcG9zaXRpb25Nb2RlLCBzdGF0dXMpLAogICAgICAgICAgICBzdGF0dXMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBVQ29sQXR0cmlidXRlVmFsdWUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDogZGF0YUlzT3duZWQoRkFMU0UpCnsKICBjb25zdHJ1Y3QocnVsZXMsCiAgICAgICAgICAgIGdldFVDb2xsYXRpb25TdHJlbmd0aChjb2xsYXRpb25TdHJlbmd0aCksCiAgICAgICAgICAgIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICBzdGF0dXMpOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3QoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNvbEF0dHJpYnV0ZVZhbHVlIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDb2xBdHRyaWJ1dGVWYWx1ZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICB1Y29sbGF0b3IgPSB1Y29sX29wZW5SdWxlcyhydWxlcy5nZXRCdWZmZXIoKSwgcnVsZXMubGVuZ3RoKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjb21wb3NpdGlvbk1vZGUsIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICZzdGF0dXMpOwogIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkKICB7CiAgICBpbnQzMl90IGxlbmd0aDsKICAgIGNvbnN0IFVDaGFyICpyID0gdWNvbF9nZXRSdWxlcyh1Y29sbGF0b3IsICZsZW5ndGgpOwogICAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgICAvLyBhbGlhcyB0aGUgcnVsZXMgc3RyaW5nCiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZyhUUlVFLCByLCBsZW5ndGgpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZygpOwogICAgfQogICAgLyogdGVzdCBmb3IgTlVMTCAqLwogICAgaWYgKHVydWxlc3RyaW5nID09IDApIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGRhdGFJc093bmVkID0gVFJVRTsKICB9Cn0KCi8qIFJ1bGVCYXNlZENvbGxhdG9yIHB1YmxpYyBkZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpSdWxlQmFzZWRDb2xsYXRvcjo6flJ1bGVCYXNlZENvbGxhdG9yKCkKewogIGlmIChkYXRhSXNPd25lZCkKICB7CiAgICB1Y29sX2Nsb3NlKHVjb2xsYXRvcik7CiAgICBkZWxldGUgdXJ1bGVzdHJpbmc7CiAgfQogIHVjb2xsYXRvciA9IDA7CiAgdXJ1bGVzdHJpbmcgPSAwOwp9CgovKiBSdWxlQmFzZUNvbGxhdG9yIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKVUJvb2wgUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIHRoYXQpIGNvbnN0CnsKICAvKiBvbmx5IGNoZWNrcyBmb3IgYWRkcmVzcyBlcXVhbHMgaGVyZSAqLwogIGlmIChDb2xsYXRvcjo6b3BlcmF0b3I9PSh0aGF0KSkKICAgIHJldHVybiBUUlVFOwoKICBpZiAoZ2V0RHluYW1pY0NsYXNzSUQoKSAhPSB0aGF0LmdldER5bmFtaWNDbGFzc0lEKCkpCiAgICByZXR1cm4gRkFMU0U7ICAvKiBub3QgdGhlIHNhbWUgY2xhc3MgKi8KCiAgUnVsZUJhc2VkQ29sbGF0b3ImIHRoYXRBbGlhcyA9IChSdWxlQmFzZWRDb2xsYXRvciYpdGhhdDsKCiAgLyoKICBzeW53ZWUgOiBvcmdpbmFsIGNvZGUgZG9lcyBub3QgY2hlY2sgZm9yIGRhdGEgY29tcGF0aWJpbGl0eQogICovCiAgaWYgKHVjb2xsYXRvciAhPSB0aGF0QWxpYXMudWNvbGxhdG9yKQogICAgcmV0dXJuIEZBTFNFOwoKICByZXR1cm4gVFJVRTsKfQoKUnVsZUJhc2VkQ29sbGF0b3ImIFJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvcj0oY29uc3QgUnVsZUJhc2VkQ29sbGF0b3ImIHRoYXQpCnsKICBpZiAodGhpcyAhPSAmdGhhdCkKICB7CiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgIHVjb2xfY2xvc2UodWNvbGxhdG9yKTsKICAgICAgdWNvbGxhdG9yID0gTlVMTDsKICAgICAgZGVsZXRlIHVydWxlc3RyaW5nOwogICAgfQoKICAgIGRhdGFJc093bmVkID0gRkFMU0U7CiAgICB1Y29sbGF0b3IgPSB0aGF0LnVjb2xsYXRvcjsKICAgIHVydWxlc3RyaW5nID0gdGhhdC51cnVsZXN0cmluZzsKICB9CiAgcmV0dXJuICp0aGlzOwp9CgpDb2xsYXRvciogUnVsZUJhc2VkQ29sbGF0b3I6OmNsb25lKCkgY29uc3QKewogIHJldHVybiBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoKnRoaXMpOwp9CgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqIFJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UpIGNvbnN0CnsKICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgKnJlc3VsdCA9IG5ldyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Ioc291cmNlLCB0aGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgZGVsZXRlIHJlc3VsdDsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqCiogQ3JlYXRlIGEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIG9iamVjdCB0aGF0IHdpbGwgaXRlcmF0b3Igb3ZlciB0aGUKKiBlbGVtZW50cyBpbiBhIHN0cmluZywgdXNpbmcgdGhlIGNvbGxhdGlvbiBydWxlcyBkZWZpbmVkIGluIHRoaXMKKiBSdWxlQmFzZWRDb2xsYXRvcgoqLwpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqIFJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2UpIGNvbnN0CnsKICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgKnJlc3VsdCA9IG5ldyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Ioc291cmNlLCB0aGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwoKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIGRlbGV0ZSByZXN1bHQ7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgoqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGNvbGxhdG9yJ3MgcnVsZXMuIFRoZSBzdHJpbmcgY2FuCiogbGF0ZXIgYmUgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgVW5pY29kZVN0cmluZyBhcmd1bWVudCwKKiB3aGljaCB3aWxsIGNvbnN0cnVjdCBhIGNvbGxhdG9yIHRoYXQncyBmdW5jdGlvbmFsbHkgaWRlbnRpY2FsIHRvIHRoaXMgb25lLgoqIFlvdSBjYW4gYWxzbyBhbGxvdyB1c2VycyB0byBlZGl0IHRoZSBzdHJpbmcgaW4gb3JkZXIgdG8gY2hhbmdlIHRoZSBjb2xsYXRpb24KKiBkYXRhLCBvciB5b3UgY2FuIHByaW50IGl0IG91dCBmb3IgaW5zcGVjdGlvbiwgb3Igd2hhdGV2ZXIuCiovCmNvbnN0IFVuaWNvZGVTdHJpbmcmIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRSdWxlcygpIGNvbnN0CnsKICAgIHJldHVybiAoKnVydWxlc3RyaW5nKTsKfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0UnVsZXMoVUNvbFJ1bGVPcHRpb24gZGVsdGEsIFVuaWNvZGVTdHJpbmcgJmJ1ZmZlcikKewogICAgaW50MzJfdCBydWxlc2l6ZSA9IHVjb2xfZ2V0UnVsZXNFeCh1Y29sbGF0b3IsIGRlbHRhLCBOVUxMLCAtMSk7CgogICAgaWYgKHJ1bGVzaXplID4gMCkgewogICAgICAgIFVDaGFyICpydWxlcyA9IChVQ2hhciopIHVwcnZfbWFsbG9jKCBzaXplb2YoVUNoYXIpICogKHJ1bGVzaXplKSApOwogICAgICAgIGlmKHJ1bGVzICE9IE5VTEwpIHsKICAgICAgICAgIHVjb2xfZ2V0UnVsZXNFeCh1Y29sbGF0b3IsIGRlbHRhLCBydWxlcywgcnVsZXNpemUpOwogICAgICAgICAgYnVmZmVyLnNldFRvKHJ1bGVzLCBydWxlc2l6ZSk7CiAgICAgICAgICB1cHJ2X2ZyZWUocnVsZXMpOwogICAgICAgIH0gZWxzZSB7IC8vIGNvdWxkbid0IGFsbG9jYXRlIAogICAgICAgICAgYnVmZmVyLnJlbW92ZSgpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgIGJ1ZmZlci5yZW1vdmUoKTsKICAgIH0KfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0VmVyc2lvbihVVmVyc2lvbkluZm8gdmVyc2lvbkluZm8pIGNvbnN0CnsKICAgIGlmICh2ZXJzaW9uSW5mbyE9TlVMTCl7CiAgICAgICAgdWNvbF9nZXRWZXJzaW9uKHVjb2xsYXRvciwgdmVyc2lvbkluZm8pOwogICAgfQp9CgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCkgY29uc3QKewogIHJldHVybiBjb21wYXJlKHNvdXJjZS5nZXRCdWZmZXIoKSwgdXBydl9taW4obGVuZ3RoLHNvdXJjZS5sZW5ndGgoKSksIHRhcmdldC5nZXRCdWZmZXIoKSwgdXBydl9taW4obGVuZ3RoLHRhcmdldC5sZW5ndGgoKSkpOwp9CgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoY29uc3QgVUNoYXIqIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNoYXIqIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdGFyZ2V0TGVuZ3RoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QKewogIHJldHVybiBnZXRFQ29tcGFyaXNvblJlc3VsdCh1Y29sX3N0cmNvbGwodWNvbGxhdG9yLCBzb3VyY2UsIHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQsIHRhcmdldExlbmd0aCkpOwp9CgovKioKKiBDb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoaXMgY29sbGF0b3IKKi8KQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IFJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCkgY29uc3QKewogIHJldHVybiBjb21wYXJlKHNvdXJjZS5nZXRCdWZmZXIoKSwgc291cmNlLmxlbmd0aCgpLCB0YXJnZXQuZ2V0QnVmZmVyKCksIHRhcmdldC5sZW5ndGgoKSk7Cn0KCi8qKgoqIFJldHJpZXZlIGEgY29sbGF0aW9uIGtleSBmb3IgdGhlIHNwZWNpZmllZCBzdHJpbmcuIFRoZSBrZXkgY2FuIGJlIGNvbXBhcmVkCiogd2l0aCBvdGhlciBjb2xsYXRpb24ga2V5cyB1c2luZyBhIGJpdHdpc2UgY29tcGFyaXNvbiAoZS5nLiBtZW1jbXApIHRvIGZpbmQKKiB0aGUgb3JkZXJpbmcgb2YgdGhlaXIgcmVzcGVjdGl2ZSBzb3VyY2Ugc3RyaW5ncy4gVGhpcyBpcyBoYW5keSB3aGVuIGRvaW5nIGEKKiBzb3J0LCB3aGVyZSBlYWNoIHNvcnQga2V5IG11c3QgYmUgY29tcGFyZWQgbWFueSB0aW1lcy4KKgoqIFRoZSBiYXNpYyBhbGdvcml0aG0gaGVyZSBpcyB0byBmaW5kIGFsbCBvZiB0aGUgY29sbGF0aW9uIGVsZW1lbnRzIGZvciBlYWNoCiogY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLCBjb252ZXJ0IHRoZW0gdG8gYW4gQVNDSUkgcmVwcmVzZW50YXRpb24sIGFuZAoqIHB1dCB0aGVtIGludG8gdGhlIGNvbGxhdGlvbiBrZXkuICBCdXQgaXQncyB0cmlja2llciB0aGFuIHRoYXQuIEVhY2gKKiBjb2xsYXRpb24gZWxlbWVudCBpbiBhIHN0cmluZyBoYXMgdGhyZWUgY29tcG9uZW50czogcHJpbWFyeSAoJ0EnIHZzICdCJyksCiogc2Vjb25kYXJ5ICgndScgdnMgJ/wnKSwgYW5kIHRlcnRpYXJ5ICgnQScgdnMgJ2EnKSwgYW5kIGEgcHJpbWFyeSBkaWZmZXJlbmNlCiogYXQgdGhlIGVuZCBvZiBhIHN0cmluZyB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgYSBzZWNvbmRhcnkgb3IgdGVydGlhcnkKKiBkaWZmZXJlbmNlIGVhcmxpZXIgaW4gdGhlIHN0cmluZy4KKgoqIFRvIGFjY291bnQgZm9yIHRoaXMsIHdlIHB1dCBhbGwgb2YgdGhlIHByaW1hcnkgb3JkZXJzIGF0IHRoZSBiZWdpbm5pbmcgb2YKKiB0aGUgc3RyaW5nLCBmb2xsb3dlZCBieSB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBvcmRlcnMuIEVhY2ggc2V0IG9mCiogb3JkZXJzIGlzIHRlcm1pbmF0ZWQgYnkgbnVsbHMgc28gdGhhdCBhIGtleSBmb3IgYSBzdHJpbmcgd2hpY2ggaXMgYSBpbml0aWFsCiogc3Vic3RyaW5nIG9mIGFub3RoZXIga2V5IHdpbGwgY29tcGFyZSBsZXNzIHdpdGhvdXQgYW55IHNwZWNpYWwgY2FzZS4KKgoqIEhlcmUncyBhIGh5cG90aGV0aWNhbCBleGFtcGxlLCB3aXRoIHRoZSBjb2xsYXRpb24gZWxlbWVudCByZXByZXNlbnRlZCBhcyBhCiogdGhyZWUtZGlnaXQgbnVtYmVyLCBvbmUgZGlnaXQgZm9yIHByaW1hcnksIG9uZSBmb3Igc2Vjb25kYXJ5LCBldGMuCioKKiBTdHJpbmc6ICAgICAgICAgICAgICBBICAgICBhICAgICBCICAgIMkKKiBDb2xsYXRpb24gRWxlbWVudHM6IDEwMSAgIDEwMCAgIDIwMSAgNTExCiogQ29sbGF0aW9uIEtleTogICAgICAxMTI1PG51bGw+MDAwMTxudWxsPjEwMTE8bnVsbD4KKgoqIFRvIG1ha2UgdGhpbmdzIGV2ZW4gdHJpY2tpZXIsIHNlY29uZGFyeSBkaWZmZXJlbmNlcyAoYWNjZW50IG1hcmtzKSBhcmUKKiBjb21wYXJlZCBzdGFydGluZyBhdCB0aGUgKmVuZCogb2YgdGhlIHN0cmluZyBpbiBsYW5ndWFnZXMgd2l0aCBGcmVuY2gKKiBzZWNvbmRhcnkgb3JkZXJpbmcuIEJ1dCB3aGVuIGNvbXBhcmluZyB0aGUgYWNjZW50IG1hcmtzIG9uIGEgc2luZ2xlIGJhc2UKKiBjaGFyYWN0ZXIsIHRoZXkgYXJlIGNvbXBhcmVkIGZyb20gdGhlIGJlZ2lubmluZy4gVG8gaGFuZGxlIHRoaXMsIHdlIHJldmVyc2UKKiBhbGwgb2YgdGhlIGFjY2VudHMgdGhhdCBiZWxvbmcgdG8gZWFjaCBiYXNlIGNoYXJhY3RlciwgdGhlbiB3ZSByZXZlcnNlIHRoZQoqIGVudGlyZSBzdHJpbmcgb2Ygc2Vjb25kYXJ5IG9yZGVyaW5ncyBhdCB0aGUgZW5kLgoqLwpDb2xsYXRpb25LZXkmIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb2xsYXRpb25LZXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgc29ydGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0CnsKICByZXR1cm4gZ2V0Q29sbGF0aW9uS2V5KHNvdXJjZS5nZXRCdWZmZXIoKSwgc291cmNlLmxlbmd0aCgpLCBzb3J0a2V5LCBzdGF0dXMpOwp9CgpDb2xsYXRpb25LZXkmIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb2xsYXRpb25LZXkoY29uc3QgVUNoYXIqIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdAp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogIHsKICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICB9CgogIGlmICgoIXNvdXJjZSkgfHwgKHNvdXJjZUxlbiA9PSAwKSkgewogICAgcmV0dXJuIHNvcnRrZXkucmVzZXQoKTsKICB9CgogIHVpbnQ4X3QgKnJlc3VsdDsKICBpbnQzMl90IHJlc3VsdExlbiA9IHVjb2xfZ2V0U29ydEtleVdpdGhBbGxvY2F0aW9uKHVjb2xsYXRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZSwgc291cmNlTGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdGF0dXMpOwogIHNvcnRrZXkuYWRvcHQocmVzdWx0LCByZXN1bHRMZW4pOwogIHJldHVybiBzb3J0a2V5Owp9CgovKioKICogUmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNlcXVlbmNlcyB0aGF0IGVuZCB3aXRoIHRoZQogKiBzcGVjaWZpZWQgY29tcGFyaXNvbiBvcmRlci4KICogQHBhcmFtIG9yZGVyIGEgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCiAqIEByZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2V1ZW5jZXMgZW5kaW5nIHdpdGggdGhlCiAqICAgICAgICAgc3BlY2lmaWVkIG9yZGVyIG9yIDEgaWYgY29sbGF0aW9uIG9yZGVyIGRvZXMgbm90IG9jY3VyIGF0IHRoZSBlbmQgb2YgYW55CiAqICAgICAgICAgZXhwYW5zaW9uIHNlcXVlbmNlLgogKiBAc2VlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciNnZXRNYXhFeHBhbnNpb24KICovCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldE1heEV4cGFuc2lvbihpbnQzMl90IG9yZGVyKSBjb25zdAp7CiAgdWludDhfdCByZXN1bHQ7CiAgVUNPTF9HRVRNQVhFWFBBTlNJT04odWNvbGxhdG9yLCAodWludDMyX3Qpb3JkZXIsIHJlc3VsdCk7CiAgcmV0dXJuIHJlc3VsdDsKfQoKdWludDhfdCogUnVsZUJhc2VkQ29sbGF0b3I6OmNsb25lUnVsZURhdGEoaW50MzJfdCAmbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKQp7CiAgcmV0dXJuIHVjb2xfY2xvbmVSdWxlRGF0YSh1Y29sbGF0b3IsICZsZW5ndGgsICZzdGF0dXMpOwp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNvbEF0dHJpYnV0ZVZhbHVlIHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwogIHVjb2xfc2V0QXR0cmlidXRlKHVjb2xsYXRvciwgYXR0ciwgdmFsdWUsICZzdGF0dXMpOwp9CgpVQ29sQXR0cmlidXRlVmFsdWUgUnVsZUJhc2VkQ29sbGF0b3I6OmdldEF0dHJpYnV0ZShVQ29sQXR0cmlidXRlIGF0dHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybiBVQ09MX0RFRkFVTFQ7CiAgcmV0dXJuIHVjb2xfZ2V0QXR0cmlidXRlKHVjb2xsYXRvciwgYXR0ciwgJnN0YXR1cyk7Cn0KCnVpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRWYXJpYWJsZVRvcChjb25zdCBVQ2hhciAqdmFyVG9wLCBpbnQzMl90IGxlbiwgVUVycm9yQ29kZSAmc3RhdHVzKSB7CiAgcmV0dXJuIHVjb2xfc2V0VmFyaWFibGVUb3AodWNvbGxhdG9yLCB2YXJUb3AsIGxlbiwgJnN0YXR1cyk7Cn0KCnVpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRWYXJpYWJsZVRvcChjb25zdCBVbmljb2RlU3RyaW5nIHZhclRvcCwgVUVycm9yQ29kZSAmc3RhdHVzKSB7CiAgcmV0dXJuIHVjb2xfc2V0VmFyaWFibGVUb3AodWNvbGxhdG9yLCB2YXJUb3AuZ2V0QnVmZmVyKCksIHZhclRvcC5sZW5ndGgoKSwgJnN0YXR1cyk7Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldFZhcmlhYmxlVG9wKGNvbnN0IHVpbnQzMl90IHZhclRvcCwgVUVycm9yQ29kZSAmc3RhdHVzKSB7CiAgdWNvbF9yZXN0b3JlVmFyaWFibGVUb3AodWNvbGxhdG9yLCB2YXJUb3AsICZzdGF0dXMpOwp9Cgp1aW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0VmFyaWFibGVUb3AoVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdCB7CiAgcmV0dXJuIHVjb2xfZ2V0VmFyaWFibGVUb3AodWNvbGxhdG9yLCAmc3RhdHVzKTsKfQoKQ29sbGF0b3IqIFJ1bGVCYXNlZENvbGxhdG9yOjpzYWZlQ2xvbmUodm9pZCkKewogIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIGludDMyX3QgYnVmZmVyc2l6ZSA9IFVfQ09MX1NBRkVDTE9ORV9CVUZGRVJTSVpFOwogIFVDb2xsYXRvciAqdWNvbCA9IHVjb2xfc2FmZUNsb25lKHVjb2xsYXRvciwgTlVMTCwgJmJ1ZmZlcnNpemUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZpbnRTdGF0dXMpOwogIGlmIChVX0ZBSUxVUkUoaW50U3RhdHVzKSkgewogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBVbmljb2RlU3RyaW5nICpyID0gbmV3IFVuaWNvZGVTdHJpbmcoKnVydWxlc3RyaW5nKTsKICBSdWxlQmFzZWRDb2xsYXRvciAqcmVzdWx0ID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHVjb2wsIHIpOwogIHJlc3VsdC0+ZGF0YUlzT3duZWQgPSBUUlVFOwogIHJldHVybiByZXN1bHQ7Cn0KCgppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRTb3J0S2V5KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90ICpyZXN1bHQsIGludDMyX3QgcmVzdWx0TGVuZ3RoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0CnsKICByZXR1cm4gdWNvbF9nZXRTb3J0S2V5KHVjb2xsYXRvciwgc291cmNlLmdldEJ1ZmZlcigpLCBzb3VyY2UubGVuZ3RoKCksIHJlc3VsdCwgcmVzdWx0TGVuZ3RoKTsKfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U29ydEtleShjb25zdCBVQ2hhciAqc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLCB1aW50OF90ICpyZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0CnsKICByZXR1cm4gdWNvbF9nZXRTb3J0S2V5KHVjb2xsYXRvciwgc291cmNlLCBzb3VyY2VMZW5ndGgsIHJlc3VsdCwgcmVzdWx0TGVuZ3RoKTsKfQoKQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U3RyZW5ndGgodm9pZCkgY29uc3QKewogIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIHJldHVybiBnZXRFQ29sbGF0aW9uU3RyZW5ndGgodWNvbF9nZXRBdHRyaWJ1dGUodWNvbGxhdG9yLCBVQ09MX1NUUkVOR1RILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmludFN0YXR1cykpOwp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRTdHJlbmd0aChFQ29sbGF0aW9uU3RyZW5ndGggbmV3U3RyZW5ndGgpCnsKICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICBVQ29sbGF0aW9uU3RyZW5ndGggc3RyZW5ndGggPSBnZXRVQ29sbGF0aW9uU3RyZW5ndGgobmV3U3RyZW5ndGgpOwogIHVjb2xfc2V0QXR0cmlidXRlKHVjb2xsYXRvciwgVUNPTF9TVFJFTkdUSCwgc3RyZW5ndGgsICZpbnRTdGF0dXMpOwp9CgovKioKKiBDcmVhdGUgYSBoYXNoIGNvZGUgZm9yIHRoaXMgY29sbGF0aW9uLiBKdXN0IGhhc2ggdGhlIG1haW4gcnVsZSB0YWJsZSAtLSB0aGF0Ciogc2hvdWxkIGJlIGdvb2QgZW5vdWdoIGZvciBhbG1vc3QgYW55IHVzZS4KKi8KaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6aGFzaENvZGUoKSBjb25zdAp7CiAgaW50MzJfdCBsZW5ndGg7CiAgY29uc3QgVUNoYXIgKnJ1bGVzID0gdWNvbF9nZXRSdWxlcyh1Y29sbGF0b3IsICZsZW5ndGgpOwogIHJldHVybiB1aGFzaF9oYXNoVUNoYXJzTihydWxlcywgbGVuZ3RoKTsKfQoKLyoqCiogcmV0dXJuIHRoZSBsb2NhbGUgb2YgdGhpcyBjb2xsYXRvcgoqLwpjb25zdCBMb2NhbGUgUnVsZUJhc2VkQ29sbGF0b3I6OmdldExvY2FsZShVTG9jRGF0YUxvY2FsZVR5cGUgdHlwZSwgVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdCB7CiAgY29uc3QgY2hhciAqcmVzdWx0ID0gdWNvbF9nZXRMb2NhbGUodWNvbGxhdG9yLCB0eXBlLCAmc3RhdHVzKTsKICBpZihyZXN1bHQgPT0gTlVMTCkgewogICAgTG9jYWxlIHJlcygiIik7CiAgICByZXMuc2V0VG9Cb2d1cygpOwogICAgcmV0dXJuIHJlczsKICB9IGVsc2UgewogICAgcmV0dXJuIExvY2FsZShyZXN1bHQpOwogIH0KfQoKLyoqCiogU2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIENvbGxhdG9yIG9iamVjdC4KKiBAcGFyYW0gdGhlIG5ldyBkZWNvbXBvc2l0aW9uIG1vZGUKKiBAc2VlIENvbGxhdG9yI2dldERlY29tcG9zaXRpb24KKi8Kdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpFTW9kZSAgbW9kZSkKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIHVjb2xfc2V0Tm9ybWFsaXphdGlvbih1Y29sbGF0b3IsIE5vcm1hbGl6ZXI6OmdldFVOb3JtYWxpemF0aW9uTW9kZShtb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpKTsKfQoKLyoqCiogR2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIENvbGxhdG9yIG9iamVjdC4KKiBAcmV0dXJuIHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUKKiBAc2VlIENvbGxhdG9yI3NldERlY29tcG9zaXRpb24KKi8KTm9ybWFsaXplcjo6RU1vZGUgUnVsZUJhc2VkQ29sbGF0b3I6OmdldERlY29tcG9zaXRpb24odm9pZCkgY29uc3QKewogIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIHJldHVybiBOb3JtYWxpemVyOjpnZXROb3JtYWxpemVyRU1vZGUodWNvbF9nZXROb3JtYWxpemF0aW9uKHVjb2xsYXRvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKfQoKLy8gUnVsZUJhc2VDb2xsYXRvck5ldyBwcml2YXRlIGNvbnN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcigpIDogZGF0YUlzT3duZWQoRkFMU0UpLCB1Y29sbGF0b3IoMCkKewp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoVUNvbGxhdG9yICpjb2xsYXRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgKnJ1bGUpIDogZGF0YUlzT3duZWQoRkFMU0UpCnsKICB1Y29sbGF0b3IgPSBjb2xsYXRvcjsKICB1cnVsZXN0cmluZyA9IHJ1bGU7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBMb2NhbGUmIGRlc2lyZWRMb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFJc093bmVkKEZBTFNFKSwgdWNvbGxhdG9yKDApCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm47CgogIC8qCiAgVHJ5IHRvIGxvYWQsIGluIG9yZGVyOgogICAxLiBUaGUgZGVzaXJlZCBsb2NhbGUncyBjb2xsYXRpb24uCiAgIDIuIEEgZmFsbGJhY2sgb2YgdGhlIGRlc2lyZWQgbG9jYWxlLgogICAzLiBUaGUgZGVmYXVsdCBsb2NhbGUncyBjb2xsYXRpb24uCiAgIDQuIEEgZmFsbGJhY2sgb2YgdGhlIGRlZmF1bHQgbG9jYWxlLgogICA1LiBUaGUgZGVmYXVsdCBjb2xsYXRpb24gcnVsZXMsIHdoaWNoIGNvbnRhaW5zIGVuX1VTIGNvbGxhdGlvbiBydWxlcy4KCiAgIFRvIHJlaXRlcmF0ZSwgd2UgdHJ5OgogICBTcGVjaWZpYzoKICAgIGxhbmd1YWdlK2NvdW50cnkrdmFyaWFudAogICAgbGFuZ3VhZ2UrY291bnRyeQogICAgbGFuZ3VhZ2UKICAgRGVmYXVsdDoKICAgIGxhbmd1YWdlK2NvdW50cnkrdmFyaWFudAogICAgbGFuZ3VhZ2UrY291bnRyeQogICAgbGFuZ3VhZ2UKICAgUm9vdDogKGFrYSBERUZBVUxUUlVMRVMpCiAgIHN0ZXBzIDEtNSBhcmUgaGFuZGxlZCBieSByZXNvdXJjZSBidW5kbGUgZmFsbGJhY2sgbWVjaGFuaXNtLgogICBob3dldmVyLCBpbiBhIHZlcnkgdW5wcm9iYWJsZSBzaXR1YXRpb24gdGhhdCBubyByZXNvdXJjZSBidW5kbGUKICAgZGF0YSBleGlzdHMsIHN0ZXAgNSBpcyByZXBlYXRlZCB3aXRoIGhhcmRjb2RlZCBkZWZhdWx0IHJ1bGVzLgogICovCgogIHNldFVDb2xsYXRvcihkZXNpcmVkTG9jYWxlLCBzdGF0dXMpOwoKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgewogICAgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIHNldFVDb2xsYXRvcihrUm9vdExvY2FsZU5hbWUsIHN0YXR1cyk7CiAgICBpZiAoc3RhdHVzID09IFVfWkVST19FUlJPUikgewogICAgICAgIHN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKICAgIH0KICB9CgogIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkKICB7CiAgICBpbnQzMl90IGxlbmd0aDsKICAgIGNvbnN0IFVDaGFyICpyID0gdWNvbF9nZXRSdWxlcyh1Y29sbGF0b3IsICZsZW5ndGgpOwogICAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgICAvLyBhbGlhcyB0aGUgcnVsZXMgc3RyaW5nCiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZyhUUlVFLCByLCBsZW5ndGgpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZygpOwogICAgfQogICAgLyogdGVzdCBmb3IgTlVMTCAqLwogICAgaWYgKHVydWxlc3RyaW5nID09IDApIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGRhdGFJc093bmVkID0gVFJVRTsKICB9CgogIHJldHVybjsKfQoKLyogUnVsZUJhc2VkQ29sbGF0b3IgcHJpdmF0ZSBkYXRhIG1lbWJlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qCiAqIFRPRE86CiAqIFRoZXNlIHNob3VsZCBwcm9iYWJseSBiZSBlbnVtcyAoPD0weGZmZmYpIG9yICNkZWZpbmVzICg+MHhmZmZmKQogKiBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlLgogKiBJbmNsdWRlIHVjb2xfaW1wLmggYW5kIHVzZSBpdHMgY29uc3RhbnRzIGlmIHBvc3NpYmxlLgogKiBPbmx5IHVzZWQgaW4gY29sZWl0ci5oPyEKICogUmVtb3ZlIGZyb20gaGVyZSEKICovCgovKiBuZWVkIGxvb2sgdXAgaW4gLmNvbW1pdCgpICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNIQVJJTkRFWCA9IDB4NzAwMDAwMDA7Ci8qIEV4cGFuZCBpbmRleCBmb2xsb3dzICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkVYUEFORENIQVJJTkRFWCA9IDB4N0UwMDAwMDA7Ci8qIGNvbnRyYWN0IGluZGV4ZXMgZm9sbG93cyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDT05UUkFDVENIQVJJTkRFWCA9IDB4N0YwMDAwMDA7Ci8qIHVubWFwcGVkIGNoYXJhY3RlciB2YWx1ZXMgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6VU5NQVBQRUQgPSAweEZGRkZGRkZGOwovKiBwcmltYXJ5IHN0cmVuZ3RoIGluY3JlbWVudCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDEwMDAwOwovKiBzZWNvbmRhcnkgc3RyZW5ndGggaW5jcmVtZW50ICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAwMDEwMDsKLyogdGVydGlhcnkgc3RyZW5ndGggaW5jcmVtZW50ICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMDAxOwovKiBtYXNrIG9mZiBhbnl0aGluZyBidXQgcHJpbWFyeSBvcmRlciAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLID0gMHhmZmZmMDAwMDsKLyogbWFzayBvZmYgYW55dGhpbmcgYnV0IHNlY29uZGFyeSBvcmRlciAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUk1BU0sgPSAweDAwMDBmZjAwOwovKiBtYXNrIG9mZiBhbnl0aGluZyBidXQgdGVydGlhcnkgb3JkZXIgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6VEVSVElBUllPUkRFUk1BU0sgPSAweDAwMDAwMGZmOwovKiBtYXNrIG9mZiBpZ25vcmFibGUgY2hhciBvcmRlciAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpJR05PUkFCTEVNQVNLID0gMHgwMDAwZmZmZjsKLyogdXNlIG9ubHkgdGhlIHByaW1hcnkgZGlmZmVyZW5jZSAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmYwMDAwOwovKiB1c2Ugb25seSB0aGUgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IGRpZmZlcmVuY2UgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmZmZjAwOwovKiBwcmltYXJ5IG9yZGVyIHNoaWZ0ICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUlNISUZUID0gMTY7Ci8qIHNlY29uZGFyeSBvcmRlciBzaGlmdCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUlNISUZUID0gODsKLyogc3RhcnRpbmcgdmFsdWUgZm9yIGNvbGxhdGlvbiBlbGVtZW50cyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDT0xFTEVNRU5UU1RBUlQgPSAweDAyMDIwMjAyOwovKiB0ZXN0aW5nIG1hc2sgZm9yIHByaW1hcnkgbG93IGVsZW1lbnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWUxPV1pFUk9NQVNLID0gMHgwMEZGMDAwMDsKLyogcmVzZXRpbmcgdmFsdWUgZm9yIHNlY29uZGFyaWVzIGFuZCB0ZXJ0aWFyaWVzICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlJFU0VUU0VDT05EQVJZVEVSVElBUlkgPSAweDAwMDAwMjAyOwovKiByZXNldGluZyB2YWx1ZSBmb3IgdGVydGlhcmllcyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpSRVNFVFRFUlRJQVJZID0gMHgwMDAwMDAwMjsKCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1JR05PUkFCTEUgPSAweDAyMDI7CgovKiB1bmlxdWUgZmlsZSBpZCBmb3IgcGFyaXR5IGNoZWNrICovCmNvbnN0IGludDE2X3QgUnVsZUJhc2VkQ29sbGF0b3I6OkZJTEVJRCA9IDB4NTQ0MzsKLyogYmluYXJ5IGNvbGxhdGlvbiBmaWxlIGV4dGVuc2lvbiAqLwpjb25zdCBjaGFyIFJ1bGVCYXNlZENvbGxhdG9yOjprRmlsZW5hbWVTdWZmaXhbXSA9ICIuY29sIjsKLyogY2xhc3MgaWQgPyBWYWx1ZSBpcyBpcnJlbGV2YW50ICovCmNvbnN0IGNoYXIgIFJ1bGVCYXNlZENvbGxhdG9yOjpmZ0NsYXNzSUQgPSAwOwoKVV9OQU1FU1BBQ0VfRU5ECg==