LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogQ29weXJpZ2h0IChDKSB7MTk5Ni0yMDAxfSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCi8qKgoqIEZpbGUgdGJsY29sbC5jcHAKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqICAyLzUvOTcgICAgICBhbGl1ICAgICAgICBBZGRlZCBzdHJlYW1JbiBhbmQgc3RyZWFtT3V0IG1ldGhvZHMuICBBZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciB3aGljaCByZWFkcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbQoqICAgICAgICAgICAgICAgICAgICAgICAgICBhIGJpbmFyeSBmaWxlLiAgQWRkZWQgd3JpdGVUb0ZpbGUgbWV0aG9kIHdoaWNoIHN0cmVhbXMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3Igb3V0IHRvIGEgYmluYXJ5IGZpbGUuICBUaGUgc3RyZWFtSW4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIHN0cmVhbU91dCBtZXRob2RzIHVzZSBpc3RyZWFtIGFuZCBvc3RyZWFtIG9iamVjdHMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gYmluYXJ5IG1vZGUuCiogIDIvMTEvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIGRlY2xhcmF0aW9ucyBvdXQgb2YgZm9yIGxvb3AgaW5pdGlhbGl6ZXIuCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIE1hYyBjb21wYXRpYmlsaXR5ICNpZmRlZiBmb3IgaW9zOjpub2NyZWF0ZS4KKiAgMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gdXNlIFRhYmxlQ29sbGF0aW9uRGF0YSBzdWItb2JqZWN0IHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGQgaW52YXJpYW50IGRhdGEuCiogIDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBpbnRvIHRoaXMgY2xhc3MgZnJvbSBDb2xsYXRpb24uCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIGEgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKSBjb25zdHJ1Y3RvciwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgdXNlZCBieSBDb2xsYXRvcjo6Z2V0SW5zdGFuY2UoKS4gIEdlbmVyYWwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW4gdXAuICBNYWRlIHVzZSBvZiBVRXJyb3JDb2RlIHZhcmlhYmxlcyBjb25zaXN0ZW50LgoqICAyLzIwLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjbG9uZSwgb3BlcmF0b3I9PSwgb3BlcmF0b3IhPSwgb3BlcmF0b3I9LCBhbmQgY29weQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBhbmQgZ2V0RHluYW1pY0NsYXNzSUQuCiogIDMvNS85NyAgICAgIGFsaXUgICAgICAgIENoYW5nZWQgY29tcGFjdGlvbiBjeWNsZSB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLiAgV2UKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlIHRoZSBtYXhpbXVtIGFsbG93YWJsZSB2YWx1ZSB3aGljaCBpcyBrQmxvY2tDb3VudC4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgTW9kaWZpZWQgZ2V0UnVsZXMoKSB0byBsb2FkIHJ1bGVzIGR5bmFtaWNhbGx5LiAgQ2hhbmdlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RGcm9tRmlsZSgpIGNhbGwgdG8gYWNjb21vZGF0ZSB0aGlzIChhZGRlZAoqICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgdG8gc3BlY2lmeSB3aGV0aGVyIGJpbmFyeSBsb2FkaW5nIGlzIHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRha2UgcGxhY2UpLgoqIDA1LzA2Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBtZW1vcnkgYWxsb2NhdGlvbiBlcnJvciBjaGVjay4KKiAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KKiAgNi8yMy85NyAgICAgaGVsZW5hICAgICAgQWRkaW5nIGNvbW1lbnRzIHRvIG1ha2UgY29kZSBtb3JlIHJlYWRhYmxlLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwNi8yNi85OCAgICAgZXJtICAgICAgICAgQ2hhbmdlcyBmb3IgQ29sbGF0aW9uS2V5cyB1c2luZyBieXRlIGFycmF5cy4KKiAwOC8xMC85OCAgICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIG9mIFJ1bGVCYXNlZENvbGxhdG9yLmphdmEKKiAwNC8yMy85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBFRGVjb21wb3NpdGlvbk1vZGUsIG1lcmdlZCB3aXRoCiogICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlCiogMDYvMTQvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQga1Jlc291cmNlQnVuZGxlU3VmZml4CiogMDYvMjIvOTkgICAgIHN0ZXBoZW4gICAgIEZpeGVkIGxvZ2ljIGluIGNvbnN0cnVjdEZyb21GaWxlKCkgc2luY2UgLmN0eAoqICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlcyBhcmUgbm8gbG9uZ2VyIHVzZWQuCiogMTEvMDIvOTkgICAgIGhlbGVuYSAgICAgIENvbGxhdG9yIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50cy4gIFNwZWNpYWwgY2FzZQoqICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgTk9fT1Agc2l0dWF0aW9ucy4KKiAxMS8xNy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluZWQgc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMuCiogMTIvMTUvOTkgICAgIGFsaXUgICAgICAgIFVwZGF0ZSB0byBzdXBwb3J0IFRoYWkgY29sbGF0aW9uLiAgTW92ZSBOb3JtYWxpemVySXRlcmF0b3IKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gaW1wbGVtZW50YXRpb24gZmlsZS4KKiAwMS8yOS8wMSAgICAgc3lud2VlICAgICAgTW9kaWZpZWQgaW50byBhIEMrKyB3cmFwcGVyIGNhbGxpbmcgQyBBUElzICh1Y29sLmgpCiovCgojaW5jbHVkZSAidWNvbF9pbXAuaCIKI2luY2x1ZGUgInVuaWNvZGUvdGJsY29sbC5oIgojaW5jbHVkZSAidW5pY29kZS9jb2xlaXRyLmgiCiNpbmNsdWRlICJ1aGFzaC5oIgojaW5jbHVkZSAidW5pY29kZS9yZXNidW5kLmgiCiNpbmNsdWRlICJjbWVtb3J5LmgiCgojaWZkZWYgX0RFQlVHCiAgI2luY2x1ZGUgInVuaXN0cm0uaCIKI2VuZGlmCgovKiBnbG9iYWwgdmFyaWFibGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyoKc3lud2VlIDogdXNpbmcgYW5vdGhlciBuYW1lIGZvciB0aGlzCmNvbnN0IHVpbnQzMl90IHRibGNvbGxfU1RBQ0tfQlVGRkVSX0xFTkdUSF8gPSAxMDI0OwoqLwojZGVmaW5lIFNUQUNLX0JVRkZFUl9MRU5HVEhfIDEwMjQKCi8qIGZvcndhcmQgZGVjbGFyYXRpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpVX0NBUEkgVUNoYXIgZm9yd2FyZENoYXJJdGVyYXRvckdsdWUodm9pZCAqaXRlcmF0b3IpOwoKLyogUnVsZUJhc2VkQ29sbGF0b3IgZGVjbGFyYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpUaGUgZm9sbG93aW5nIGRpYWdyYW0gc2hvd3MgdGhlIGRhdGEgc3RydWN0dXJlIG9mIHRoZSBSdWxlQmFzZWRDb2xsYXRvciAgb2JqZWN0LgpTdXBwb3NlIHdlIGhhdmUgdGhlIHJ1bGUsIHdoZXJlICdvLXVtbGF1dCcgaXMgdGhlIHVuaWNvZGUgY2hhciAweDAwRjYuCiJhLCBBIDwgYiwgQiA8IGMsIEMsIGNoLCBjSCwgQ2gsIENIIDwgZCwgRCAuLi4gPCBvLCBPOwonby11bWxhdXQnL0UsICdPLXVtbGF1dCcvRSAuLi4iLgpXaGF0IHRoZSBydWxlIHNheXMgaXMsIHNvcnRzICdjaCdsaWdhdHVyZXMgYW5kICdjJyBvbmx5IHdpdGggdGVydGlhcnkKZGlmZmVyZW5jZSBhbmQgc29ydHMgJ28tdW1sYXV0JyBhcyBpZiBpdCdzIGFsd2F5cyBleHBhbmRlZCB3aXRoICdlJy4KCm1hcHBpbmcgdGFibGUgICAgICAgICAgICAgICAgIGNvbnRyYWN0aW5nIGxpc3QgICAgICAgICAgICAgZXhwYW5kaW5nIGxpc3QKKGNvbnRhaW5zIGFsbCB1bmljb2RlCmNoYXIgZW50cmllcykgICAgICAgICAgICAgICBfX18gICAgX19fX19fX19fX19fICAgICAgX19fX19fX19fX19fX19fX19fX19fX19fXwogX19fX19fX18gICAgICAgICAgICAgICAgfD0+fF8qX3wtPnwnYycgfHYoJ2MnKSB8IHw9Pnx2KCdvJyl8digndW1sYXV0Jyl8dignZScpfAp8X1x1MDAwMV98LT4gdignXHUwMDAxJykgfCAgfF86X3wgIHwtLS0tLS0tLS0tLS18IHwgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAp8X1x1MDAwMl98LT4gdignXHUwMDAyJykgfCAgfF86X3wgIHwnY2gnfHYoJ2NoJyl8IHwgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAp8X19fXzpfX198ICAgICAgICAgICAgICAgfCAgfF86X3wgIHwtLS0tLS0tLS0tLS18IHwgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAp8X19fXzpfX198ICAgICAgICAgICAgICAgfCAgICAgICAgIHwnY0gnfHYoJ2NIJyl8IHwgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAp8X18nYSdfX198LT4gdignYScpICAgICAgfCAgICAgICAgIHwtLS0tLS0tLS0tLS18IHwgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAp8X18nYidfX198LT4gdignYicpICAgICAgfCAgICAgICAgIHwnQ2gnfHYoJ0NoJyl8IHwgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAp8X19fXzpfX198ICAgICAgICAgICAgICAgfCAgICAgICAgIHwtLS0tLS0tLS0tLS18IHwgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAp8X19fXzpfX198ICAgICAgICAgICAgICAgfCAgICAgICAgIHwnQ0gnfHYoJ0NIJyl8IHwgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAp8X19fJ2MnX198LS0tLS0tLS0tLS0tLS0tLSAgICAgICAgICAtLS0tLS0tLS0tLS0gIHwgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAp8X19fXzpfX198ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAp8by11bWxhdXR8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgIHxfX19fX19fX19fX19fX19fX19fX19fX19ffAp8X19fXzpfX198CgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qIHB1YmxpYyBSdWxlQmFzZWRDb2xsYXRvciBjb25zdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioKKiBDb3B5IGNvbnN0cnVjdG9yCiovClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdCkgOgogICAgICAgICAgICAgIENvbGxhdG9yKHRoYXQpLCBkYXRhSXNPd25lZChGQUxTRSksIHVjb2xsYXRvcih0aGF0LnVjb2xsYXRvciksCiAgICAgICAgICAgICAgdXJ1bGVzdHJpbmcodGhhdC51cnVsZXN0cmluZykKewp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwoKICBpbnQzMl90IGxlbmd0aCA9IHJ1bGVzLmxlbmd0aCgpOwoKICBVQ2hhciB1Y2hhcnJ1bGVzW1NUQUNLX0JVRkZFUl9MRU5HVEhfXTsKICBVQ2hhciAqcHVjaGFycnVsZXMgPSB1Y2hhcnJ1bGVzOwoKICBpZiAobGVuZ3RoID49IFNUQUNLX0JVRkZFUl9MRU5HVEhfKQogICAgcHVjaGFycnVsZXMgPSBuZXcgVUNoYXJbbGVuZ3RoICsgMV07CgogIHJ1bGVzLmV4dHJhY3QoMCwgbGVuZ3RoLCBwdWNoYXJydWxlcyk7CiAgcHVjaGFycnVsZXNbbGVuZ3RoXSA9IDA7CgogIHVjb2xsYXRvciA9IHVjb2xfb3BlblJ1bGVzKHB1Y2hhcnJ1bGVzLCBsZW5ndGgsIFVDT0xfREVGQVVMVF9OT1JNQUxJWkFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDT0xfREVGQVVMVF9TVFJFTkdUSCwgJnN0YXR1cyk7CgogIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkKICB7CiAgICBjb25zdCBVQ2hhciAqciA9IHVjb2xfZ2V0UnVsZXModWNvbGxhdG9yLCAmbGVuZ3RoKTsKICAgIGlmIChsZW5ndGggPiAwKSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZyhyLCBsZW5ndGgpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZygpOwogICAgfQoKICAgIGRhdGFJc093bmVkID0gVFJVRTsKICB9CgogIGlmIChwdWNoYXJydWxlcyAhPSB1Y2hhcnJ1bGVzKQogICAgZGVsZXRlW10gcHVjaGFycnVsZXM7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOiBkYXRhSXNPd25lZChGQUxTRSkKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybjsKCiAgaW50MzJfdCBsZW5ndGggPSBydWxlcy5sZW5ndGgoKTsKCiAgVUNoYXIgdWNoYXJydWxlc1tTVEFDS19CVUZGRVJfTEVOR1RIX107CiAgVUNoYXIgKnB1Y2hhcnJ1bGVzID0gdWNoYXJydWxlczsKCiAgaWYgKGxlbmd0aCA+PSBTVEFDS19CVUZGRVJfTEVOR1RIXykKICAgIHB1Y2hhcnJ1bGVzID0gbmV3IFVDaGFyW2xlbmd0aCArIDFdOwoKICBydWxlcy5leHRyYWN0KDAsIGxlbmd0aCwgcHVjaGFycnVsZXMpOwogIHB1Y2hhcnJ1bGVzW2xlbmd0aF0gPSAwOwoKICBVQ29sbGF0aW9uU3RyZW5ndGggc3RyZW5ndGggPSBnZXRVQ29sbGF0aW9uU3RyZW5ndGgoY29sbGF0aW9uU3RyZW5ndGgpOwogIHVjb2xsYXRvciA9IHVjb2xfb3BlblJ1bGVzKHB1Y2hhcnJ1bGVzLCBsZW5ndGgsIFVDT0xfREVGQVVMVF9OT1JNQUxJWkFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVuZ3RoLCAmc3RhdHVzKTsKCiAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpKQogIHsKICAgIGNvbnN0IFVDaGFyICpyID0gdWNvbF9nZXRSdWxlcyh1Y29sbGF0b3IsICZsZW5ndGgpOwogICAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgICB1cnVsZXN0cmluZyA9IG5ldyBVbmljb2RlU3RyaW5nKHIsIGxlbmd0aCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICB1cnVsZXN0cmluZyA9IG5ldyBVbmljb2RlU3RyaW5nKCk7CiAgICB9CiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CiAgfQoKICBpZiAocHVjaGFycnVsZXMgIT0gdWNoYXJydWxlcykKICAgIGRlbGV0ZVtdIHB1Y2hhcnJ1bGVzOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm47CgogIGludDMyX3QgbGVuZ3RoID0gcnVsZXMubGVuZ3RoKCk7CgogIFVDaGFyIHVjaGFycnVsZXNbU1RBQ0tfQlVGRkVSX0xFTkdUSF9dOwogIFVDaGFyICpwdWNoYXJydWxlcyA9IHVjaGFycnVsZXM7CgogIGlmIChsZW5ndGggPj0gU1RBQ0tfQlVGRkVSX0xFTkdUSF8pCiAgICBwdWNoYXJydWxlcyA9IG5ldyBVQ2hhcltsZW5ndGggKyAxXTsKCiAgcnVsZXMuZXh0cmFjdCgwLCBsZW5ndGgsIHB1Y2hhcnJ1bGVzKTsKICBwdWNoYXJydWxlc1tsZW5ndGhdID0gMDsKCiAgVU5vcm1hbGl6YXRpb25Nb2RlIG1vZGUgPSBOb3JtYWxpemVyOjpnZXRVTm9ybWFsaXphdGlvbk1vZGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29tcG9zaXRpb25Nb2RlLCBzdGF0dXMpOwogIHVjb2xsYXRvciA9IHVjb2xfb3BlblJ1bGVzKHB1Y2hhcnJ1bGVzLCBsZW5ndGgsIG1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNPTF9ERUZBVUxUX1NUUkVOR1RILCAmc3RhdHVzKTsKCiAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpKQogIHsKICAgIGNvbnN0IFVDaGFyICpyID0gdWNvbF9nZXRSdWxlcyh1Y29sbGF0b3IsICZsZW5ndGgpOwogICAgaWYgKGxlbmd0aCA+IDApIHsKICAgICAgICB1cnVsZXN0cmluZyA9IG5ldyBVbmljb2RlU3RyaW5nKHIsIGxlbmd0aCk7ICAgIAogICAgfQogICAgZWxzZSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZygpOwogICAgfQogICAgZGF0YUlzT3duZWQgPSBUUlVFOwogIH0KCiAgaWYgKHB1Y2hhcnJ1bGVzICE9IHVjaGFycnVsZXMpCiAgICBkZWxldGVbXSBwdWNoYXJydWxlczsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIDogZGF0YUlzT3duZWQoRkFMU0UpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm47CgogIGludDMyX3QgbGVuZ3RoID0gcnVsZXMubGVuZ3RoKCk7CgogIFVDaGFyIHVjaGFycnVsZXNbU1RBQ0tfQlVGRkVSX0xFTkdUSF9dOwogIFVDaGFyICpwdWNoYXJydWxlcyA9IHVjaGFycnVsZXM7CgogIGlmIChsZW5ndGggPj0gU1RBQ0tfQlVGRkVSX0xFTkdUSF8pCiAgICBwdWNoYXJydWxlcyA9IG5ldyBVQ2hhcltsZW5ndGggKyAxXTsKCiAgcnVsZXMuZXh0cmFjdCgwLCBsZW5ndGgsIHB1Y2hhcnJ1bGVzKTsKICBwdWNoYXJydWxlc1tsZW5ndGhdID0gMDsKCiAgVUNvbGxhdGlvblN0cmVuZ3RoIHN0cmVuZ3RoID0gZ2V0VUNvbGxhdGlvblN0cmVuZ3RoKGNvbGxhdGlvblN0cmVuZ3RoKTsKICBVTm9ybWFsaXphdGlvbk1vZGUgbW9kZSA9IE5vcm1hbGl6ZXI6OmdldFVOb3JtYWxpemF0aW9uTW9kZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjb21wb3NpdGlvbk1vZGUsIHN0YXR1cyk7CiAgdWNvbGxhdG9yID0gdWNvbF9vcGVuUnVsZXMocHVjaGFycnVsZXMsIGxlbmd0aCwgbW9kZSwgc3RyZW5ndGgsICZzdGF0dXMpOwogIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkKICB7CiAgICBjb25zdCBVQ2hhciAqciA9IHVjb2xfZ2V0UnVsZXModWNvbGxhdG9yLCAmbGVuZ3RoKTsKICAgIGlmIChsZW5ndGggPiAwKSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZyhyLCBsZW5ndGgpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZygpOwogICAgfQogICAgZGF0YUlzT3duZWQgPSBUUlVFOwogIH0KCiAgaWYgKHB1Y2hhcnJ1bGVzICE9IHVjaGFycnVsZXMpCiAgICBkZWxldGVbXSBwdWNoYXJydWxlczsKfQoKCgovKiBSdWxlQmFzZWRDb2xsYXRvciBwdWJsaWMgZGVzdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKUnVsZUJhc2VkQ29sbGF0b3I6On5SdWxlQmFzZWRDb2xsYXRvcigpCnsKICBpZiAoZGF0YUlzT3duZWQpCiAgewogICAgdWNvbF9jbG9zZSh1Y29sbGF0b3IpOwogICAgZGVsZXRlIHVydWxlc3RyaW5nOwogIH0KICB1Y29sbGF0b3IgPSBOVUxMOwp9CgovKiBSdWxlQmFzZUNvbGxhdG9yIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKVUJvb2wgUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIHRoYXQpIGNvbnN0CnsKICAvKiBvbmx5IGNoZWNrcyBmb3IgYWRkcmVzcyBlcXVhbHMgaGVyZSAqLwogIGlmIChDb2xsYXRvcjo6b3BlcmF0b3I9PSh0aGF0KSkKICAgIHJldHVybiBUUlVFOwoKICBpZiAoZ2V0RHluYW1pY0NsYXNzSUQoKSAhPSB0aGF0LmdldER5bmFtaWNDbGFzc0lEKCkpCiAgICByZXR1cm4gRkFMU0U7ICAvKiBub3QgdGhlIHNhbWUgY2xhc3MgKi8KCiAgUnVsZUJhc2VkQ29sbGF0b3ImIHRoYXRBbGlhcyA9IChSdWxlQmFzZWRDb2xsYXRvciYpdGhhdDsKCiAgLyoKICBzeW53ZWUgOiBvcmdpbmFsIGNvZGUgZG9lcyBub3QgY2hlY2sgZm9yIGRhdGEgY29tcGF0aWJpbGl0eQogICovCiAgaWYgKHVjb2xsYXRvciAhPSB0aGF0QWxpYXMudWNvbGxhdG9yKQogICAgcmV0dXJuIEZBTFNFOwoKICByZXR1cm4gVFJVRTsKfQoKUnVsZUJhc2VkQ29sbGF0b3ImIFJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvcj0oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdCkKewogIGlmICh0aGlzICE9ICZ0aGF0KQogIHsKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgdWNvbF9jbG9zZSh1Y29sbGF0b3IpOwogICAgICB1Y29sbGF0b3IgPSBOVUxMOwogICAgICBkZWxldGUgdXJ1bGVzdHJpbmc7CiAgICB9CgogICAgZGF0YUlzT3duZWQgPSBGQUxTRTsKICAgIHVjb2xsYXRvciA9IHRoYXQudWNvbGxhdG9yOwogICAgdXJ1bGVzdHJpbmcgPSB0aGF0LnVydWxlc3RyaW5nOwogIH0KICByZXR1cm4gKnRoaXM7Cn0KCkNvbGxhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6Y2xvbmUoKSBjb25zdAp7CiAgcmV0dXJuIG5ldyBSdWxlQmFzZWRDb2xsYXRvcigqdGhpcyk7Cn0KCi8qKgoqIENyZWF0ZSBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGl0ZXJhdG9yIG92ZXIgdGhlCiogZWxlbWVudHMgaW4gYSBzdHJpbmcsIHVzaW5nIHRoZSBjb2xsYXRpb24gcnVsZXMgZGVmaW5lZCBpbiB0aGlzCiogUnVsZUJhc2VkQ29sbGF0b3IKKi8KQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlKSBjb25zdAp7CiAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yICpyZXN1bHQgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKCiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuIE5VTEw7CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgoqIENyZWF0ZSBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGl0ZXJhdG9yIG92ZXIgdGhlCiogZWxlbWVudHMgaW4gYSBzdHJpbmcsIHVzaW5nIHRoZSBjb2xsYXRpb24gcnVsZXMgZGVmaW5lZCBpbiB0aGlzCiogUnVsZUJhc2VkQ29sbGF0b3IKKi8KQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlKSBjb25zdAp7CiAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yICpyZXN1bHQgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKCiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuIE5VTEw7CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgoqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGNvbGxhdG9yJ3MgcnVsZXMuIFRoZSBzdHJpbmcgY2FuCiogbGF0ZXIgYmUgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgVW5pY29kZVN0cmluZyBhcmd1bWVudCwKKiB3aGljaCB3aWxsIGNvbnN0cnVjdCBhIGNvbGxhdG9yIHRoYXQncyBmdW5jdGlvbmFsbHkgaWRlbnRpY2FsIHRvIHRoaXMgb25lLgoqIFlvdSBjYW4gYWxzbyBhbGxvdyB1c2VycyB0byBlZGl0IHRoZSBzdHJpbmcgaW4gb3JkZXIgdG8gY2hhbmdlIHRoZSBjb2xsYXRpb24KKiBkYXRhLCBvciB5b3UgY2FuIHByaW50IGl0IG91dCBmb3IgaW5zcGVjdGlvbiwgb3Igd2hhdGV2ZXIuCiovCmNvbnN0IFVuaWNvZGVTdHJpbmcmIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRSdWxlcygpIGNvbnN0CnsKICByZXR1cm4gKCp1cnVsZXN0cmluZyk7Cn0KCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCBSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdAp7CiAgVW5pY29kZVN0cmluZyBzb3VyY2VfdG9nbzsKICBVbmljb2RlU3RyaW5nIHRhcmdldF90b2dvOwogIFVUZXh0T2Zmc2V0IGJlZ2luPTA7CgogIHNvdXJjZS5leHRyYWN0KGJlZ2luLCB1cHJ2X21pbihsZW5ndGgsc291cmNlLmxlbmd0aCgpKSwgc291cmNlX3RvZ28pOwogIHRhcmdldC5leHRyYWN0KGJlZ2luLCB1cHJ2X21pbihsZW5ndGgsdGFyZ2V0Lmxlbmd0aCgpKSwgdGFyZ2V0X3RvZ28pOwogIHJldHVybiBjb21wYXJlKHNvdXJjZV90b2dvLCB0YXJnZXRfdG9nbyk7Cn0KCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCBSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZShjb25zdCBVQ2hhciogc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ2hhciogdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB0YXJnZXRMZW5ndGgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdAp7CiAgcmV0dXJuIGdldEVDb21wYXJpc29uUmVzdWx0KHVjb2xfc3RyY29sbCh1Y29sbGF0b3IsIHNvdXJjZSwgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCwgdGFyZ2V0TGVuZ3RoKSk7Cn0KCi8qKgoqIENvbXBhcmUgdHdvIHN0cmluZ3MgdXNpbmcgdGhpcyBjb2xsYXRvcgoqLwpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdAp7CiAgVUNoYXIgdVNzdGFydFtTVEFDS19CVUZGRVJfTEVOR1RIX107CiAgVUNoYXIgdVRzdGFydFtTVEFDS19CVUZGRVJfTEVOR1RIX107CiAgVUNoYXIgKnVTb3VyY2UgPSB1U3N0YXJ0OwogIFVDaGFyICp1VGFyZ2V0ID0gdVRzdGFydDsKICB1aW50MzJfdCBzb3VyY2VMZW4gPSBzb3VyY2UubGVuZ3RoKCk7CiAgdWludDMyX3QgdGFyZ2V0TGVuID0gdGFyZ2V0Lmxlbmd0aCgpOwoKICBpZihzb3VyY2VMZW4gPj0gU1RBQ0tfQlVGRkVSX0xFTkdUSF8pCiAgICB1U291cmNlID0gbmV3IFVDaGFyW3NvdXJjZUxlbisxXTsKCiAgaWYodGFyZ2V0TGVuID49IFNUQUNLX0JVRkZFUl9MRU5HVEhfKQogICAgdVRhcmdldCA9IG5ldyBVQ2hhclt0YXJnZXRMZW4rMV07CgogIHNvdXJjZS5leHRyYWN0KDAsIHNvdXJjZUxlbiwgdVNvdXJjZSk7CiAgdVNvdXJjZVtzb3VyY2VMZW5dID0gMDsKICB0YXJnZXQuZXh0cmFjdCgwLCB0YXJnZXRMZW4sIHVUYXJnZXQpOwogIHVUYXJnZXRbdGFyZ2V0TGVuXSA9IDA7CiAgRUNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gY29tcGFyZSh1U291cmNlLCBzb3VyY2VMZW4sIHVUYXJnZXQsIHRhcmdldExlbik7CgogIGlmKHVTc3RhcnQgIT0gdVNvdXJjZSkKICAgIGRlbGV0ZVtdIHVTb3VyY2U7CgogIGlmKHVUc3RhcnQgIT0gdVRhcmdldCkKICAgIGRlbGV0ZVtdIHVUYXJnZXQ7CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qKgoqIFJldHJpZXZlIGEgY29sbGF0aW9uIGtleSBmb3IgdGhlIHNwZWNpZmllZCBzdHJpbmcuIFRoZSBrZXkgY2FuIGJlIGNvbXBhcmVkCiogd2l0aCBvdGhlciBjb2xsYXRpb24ga2V5cyB1c2luZyBhIGJpdHdpc2UgY29tcGFyaXNvbiAoZS5nLiBtZW1jbXApIHRvIGZpbmQKKiB0aGUgb3JkZXJpbmcgb2YgdGhlaXIgcmVzcGVjdGl2ZSBzb3VyY2Ugc3RyaW5ncy4gVGhpcyBpcyBoYW5keSB3aGVuIGRvaW5nIGEKKiBzb3J0LCB3aGVyZSBlYWNoIHNvcnQga2V5IG11c3QgYmUgY29tcGFyZWQgbWFueSB0aW1lcy4KKgoqIFRoZSBiYXNpYyBhbGdvcml0aG0gaGVyZSBpcyB0byBmaW5kIGFsbCBvZiB0aGUgY29sbGF0aW9uIGVsZW1lbnRzIGZvciBlYWNoCiogY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLCBjb252ZXJ0IHRoZW0gdG8gYW4gQVNDSUkgcmVwcmVzZW50YXRpb24sIGFuZAoqIHB1dCB0aGVtIGludG8gdGhlIGNvbGxhdGlvbiBrZXkuICBCdXQgaXQncyB0cmlja2llciB0aGFuIHRoYXQuIEVhY2gKKiBjb2xsYXRpb24gZWxlbWVudCBpbiBhIHN0cmluZyBoYXMgdGhyZWUgY29tcG9uZW50czogcHJpbWFyeSAoJ0EnIHZzICdCJyksCiogc2Vjb25kYXJ5ICgndScgdnMgJ/wnKSwgYW5kIHRlcnRpYXJ5ICgnQScgdnMgJ2EnKSwgYW5kIGEgcHJpbWFyeSBkaWZmZXJlbmNlCiogYXQgdGhlIGVuZCBvZiBhIHN0cmluZyB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgYSBzZWNvbmRhcnkgb3IgdGVydGlhcnkKKiBkaWZmZXJlbmNlIGVhcmxpZXIgaW4gdGhlIHN0cmluZy4KKgoqIFRvIGFjY291bnQgZm9yIHRoaXMsIHdlIHB1dCBhbGwgb2YgdGhlIHByaW1hcnkgb3JkZXJzIGF0IHRoZSBiZWdpbm5pbmcgb2YKKiB0aGUgc3RyaW5nLCBmb2xsb3dlZCBieSB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBvcmRlcnMuIEVhY2ggc2V0IG9mCiogb3JkZXJzIGlzIHRlcm1pbmF0ZWQgYnkgbnVsbHMgc28gdGhhdCBhIGtleSBmb3IgYSBzdHJpbmcgd2hpY2ggaXMgYSBpbml0aWFsCiogc3Vic3RyaW5nIG9mIGFub3RoZXIga2V5IHdpbGwgY29tcGFyZSBsZXNzIHdpdGhvdXQgYW55IHNwZWNpYWwgY2FzZS4KKgoqIEhlcmUncyBhIGh5cG90aGV0aWNhbCBleGFtcGxlLCB3aXRoIHRoZSBjb2xsYXRpb24gZWxlbWVudCByZXByZXNlbnRlZCBhcyBhCiogdGhyZWUtZGlnaXQgbnVtYmVyLCBvbmUgZGlnaXQgZm9yIHByaW1hcnksIG9uZSBmb3Igc2Vjb25kYXJ5LCBldGMuCioKKiBTdHJpbmc6ICAgICAgICAgICAgICBBICAgICBhICAgICBCICAgIMkKKiBDb2xsYXRpb24gRWxlbWVudHM6IDEwMSAgIDEwMCAgIDIwMSAgNTExCiogQ29sbGF0aW9uIEtleTogICAgICAxMTI1PG51bGw+MDAwMTxudWxsPjEwMTE8bnVsbD4KKgoqIFRvIG1ha2UgdGhpbmdzIGV2ZW4gdHJpY2tpZXIsIHNlY29uZGFyeSBkaWZmZXJlbmNlcyAoYWNjZW50IG1hcmtzKSBhcmUKKiBjb21wYXJlZCBzdGFydGluZyBhdCB0aGUgKmVuZCogb2YgdGhlIHN0cmluZyBpbiBsYW5ndWFnZXMgd2l0aCBGcmVuY2gKKiBzZWNvbmRhcnkgb3JkZXJpbmcuIEJ1dCB3aGVuIGNvbXBhcmluZyB0aGUgYWNjZW50IG1hcmtzIG9uIGEgc2luZ2xlIGJhc2UKKiBjaGFyYWN0ZXIsIHRoZXkgYXJlIGNvbXBhcmVkIGZyb20gdGhlIGJlZ2lubmluZy4gVG8gaGFuZGxlIHRoaXMsIHdlIHJldmVyc2UKKiBhbGwgb2YgdGhlIGFjY2VudHMgdGhhdCBiZWxvbmcgdG8gZWFjaCBiYXNlIGNoYXJhY3RlciwgdGhlbiB3ZSByZXZlcnNlIHRoZQoqIGVudGlyZSBzdHJpbmcgb2Ygc2Vjb25kYXJ5IG9yZGVyaW5ncyBhdCB0aGUgZW5kLgoqLwpDb2xsYXRpb25LZXkmIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb2xsYXRpb25LZXkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgc29ydGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0CnsKICBVQ2hhciBzU3RhcnRbU1RBQ0tfQlVGRkVSX0xFTkdUSF9dOwogIFVDaGFyICp1U291cmNlID0gc1N0YXJ0OwogIHVpbnQzMl90IHNvdXJjZUxlbiA9IHNvdXJjZS5sZW5ndGgoKTsKCiAgaWYoc291cmNlTGVuID49IFNUQUNLX0JVRkZFUl9MRU5HVEhfKQogICAgdVNvdXJjZSA9IG5ldyBVQ2hhcltzb3VyY2VMZW4rMV07CgogIHNvdXJjZS5leHRyYWN0KDAsIHNvdXJjZUxlbiwgdVNvdXJjZSk7CiAgdVNvdXJjZVtzb3VyY2VMZW5dID0gMDsKICBDb2xsYXRpb25LZXkmIHJlc3VsdCA9IGdldENvbGxhdGlvbktleSh1U291cmNlLCBzb3VyY2VMZW4sIHNvcnRrZXksIHN0YXR1cyk7CiAgaWYoc1N0YXJ0ICE9IHVTb3VyY2UpCiAgICBkZWxldGVbXSB1U291cmNlOwoKICByZXR1cm4gcmVzdWx0Owp9CgpDb2xsYXRpb25LZXkmIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb2xsYXRpb25LZXkoY29uc3QgVUNoYXIqIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdAp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogIHsKICAgIHN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICB9CgogIGlmICgoIXNvdXJjZSkgfHwgKHNvdXJjZUxlbiA9PSAwKSkKICAgIHJldHVybiBzb3J0a2V5LnJlc2V0KCk7CgogIC8qCiAgKiBoYXZlIHRvIHVzZSBtYWxsb2MsIGxvd2VzdCBkZW5vbWluYXRpb24sIHNpbmNlIGFkb3B0IGNhbiBiZSB1c2VkIGJ5CiAgKiBhIGMgcmV0dXJuIHZhbHVlLgogICovCiAgdWludDhfdCAqcmVzdWx0ID0gKHVpbnQ4X3QgKil1cHJ2X21hbGxvYyhVQ09MX01BWF9CVUZGRVIgKiBzaXplb2YodWludDhfdCkpOwogIGludDMyX3QgcmVzTGVuID0gdWNvbF9nZXRTb3J0S2V5KHVjb2xsYXRvciwgc291cmNlLCBzb3VyY2VMZW4sIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ09MX01BWF9CVUZGRVIpOwogIHNvcnRrZXkuYWRvcHQocmVzdWx0LCByZXNMZW4pOwoKICByZXR1cm4gc29ydGtleTsKfQoKLyoqCiAqIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQgd2l0aCB0aGUKICogc3BlY2lmaWVkIGNvbXBhcmlzb24gb3JkZXIuCiAqIEBwYXJhbSBvcmRlciBhIGNvbGxhdGlvbiBvcmRlciByZXR1cm5lZCBieSBwcmV2aW91cyBvciBuZXh0LgogKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNldWVuY2VzIGVuZGluZyB3aXRoIHRoZQogKiAgICAgICAgIHNwZWNpZmllZCBvcmRlciBvciAxIGlmIGNvbGxhdGlvbiBvcmRlciBkb2VzIG5vdCBvY2N1ciBhdCB0aGUgZW5kIG9mIGFueQogKiAgICAgICAgIGV4cGFuc2lvbiBzZXF1ZW5jZS4KICogQHNlZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IjZ2V0TWF4RXhwYW5zaW9uCiAqLwppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3QKewogIHVpbnQ4X3QgcmVzdWx0OwogIFVDT0xfR0VUTUFYRVhQQU5TSU9OKHVjb2xsYXRvciwgKHVpbnQzMl90KW9yZGVyLCByZXN1bHQpOwogIHJldHVybiByZXN1bHQ7Cn0KCnVpbnQ4X3QqIFJ1bGVCYXNlZENvbGxhdG9yOjpjbG9uZVJ1bGVEYXRhKGludDMyX3QgJmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykKewogIHJldHVybiB1Y29sX2Nsb25lUnVsZURhdGEodWNvbGxhdG9yLCAmbGVuZ3RoLCAmc3RhdHVzKTsKfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0QXR0cmlidXRlKFVDb2xBdHRyaWJ1dGUgYXR0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDb2xBdHRyaWJ1dGVWYWx1ZSB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHJldHVybjsKICB1Y29sX3NldEF0dHJpYnV0ZSh1Y29sbGF0b3IsIGF0dHIsIHZhbHVlLCAmc3RhdHVzKTsKfQoKVUNvbEF0dHJpYnV0ZVZhbHVlIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICByZXR1cm4gVUNPTF9ERUZBVUxUOwogIHJldHVybiB1Y29sX2dldEF0dHJpYnV0ZSh1Y29sbGF0b3IsIGF0dHIsICZzdGF0dXMpOwp9CgpDb2xsYXRvciogUnVsZUJhc2VkQ29sbGF0b3I6OnNhZmVDbG9uZSh2b2lkKQp7CiAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgaW50MzJfdCBidWZmZXJzaXplID0gVV9DT0xfU0FGRUNMT05FX0JVRkZFUlNJWkU7CiAgVUNvbGxhdG9yICp1Y29sID0gdWNvbF9zYWZlQ2xvbmUodWNvbGxhdG9yLCBOVUxMLCAmYnVmZmVyc2l6ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmludFN0YXR1cyk7CiAgaWYgKFVfRkFJTFVSRShpbnRTdGF0dXMpKQogICAgcmV0dXJuIE5VTEw7CiAgaW50MzJfdCBsZW5ndGggPSAwOwogIFVuaWNvZGVTdHJpbmcgKnIgPSBuZXcgVW5pY29kZVN0cmluZyh1Y29sX2dldFJ1bGVzKHVjb2xsYXRvciwgJmxlbmd0aCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCk7CiAgUnVsZUJhc2VkQ29sbGF0b3IgKnJlc3VsdCA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcih1Y29sLCByKTsKICByZXN1bHQtPmRhdGFJc093bmVkID0gVFJVRTsKICByZXR1cm4gcmVzdWx0Owp9CgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3J3YXJkQ2hhcmFjdGVySXRlcmF0b3IgJnNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcndhcmRDaGFyYWN0ZXJJdGVyYXRvciAmdGFyZ2V0KQp7CiAgcmV0dXJuIGdldEVDb21wYXJpc29uUmVzdWx0KAogICAgdWNvbF9zdHJjb2xsaW5jKHVjb2xsYXRvciwgZm9yd2FyZENoYXJJdGVyYXRvckdsdWUsICZzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgZm9yd2FyZENoYXJJdGVyYXRvckdsdWUsICZ0YXJnZXQpKTsKfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U29ydEtleShjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCAqcmVzdWx0LCBpbnQzMl90IHJlc3VsdExlbmd0aCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdAp7CiAgVUNoYXIgc1N0YXJ0W1NUQUNLX0JVRkZFUl9MRU5HVEhfXTsKICBVQ2hhciAqdVNvdXJjZSA9IHNTdGFydDsKICB1aW50MzJfdCBzb3VyY2VMZW4gPSBzb3VyY2UubGVuZ3RoKCk7CiAgaWYoc291cmNlTGVuID49IFNUQUNLX0JVRkZFUl9MRU5HVEhfKQogICAgdVNvdXJjZSA9IG5ldyBVQ2hhcltzb3VyY2VMZW4rMV07CgogIHNvdXJjZS5leHRyYWN0KDAsIHNvdXJjZUxlbiwgdVNvdXJjZSk7CiAgdVNvdXJjZVtzb3VyY2VMZW5dID0gMDsKCiAgaW50MzJfdCByZXNMZW4gPSB1Y29sX2dldFNvcnRLZXkodWNvbGxhdG9yLCB1U291cmNlLCBzb3VyY2VMZW4sIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMZW5ndGgpOwogIGlmKHNTdGFydCAhPSB1U291cmNlKQogICAgZGVsZXRlW10gdVNvdXJjZTsKCiAgcmV0dXJuIHJlc0xlbjsKfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U29ydEtleShjb25zdCBVQ2hhciAqc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLCB1aW50OF90ICpyZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0CnsKICByZXR1cm4gdWNvbF9nZXRTb3J0S2V5KHVjb2xsYXRvciwgc291cmNlLCBzb3VyY2VMZW5ndGgsIHJlc3VsdCwgcmVzdWx0TGVuZ3RoKTsKfQoKQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U3RyZW5ndGgodm9pZCkgY29uc3QKewogIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogIHJldHVybiBnZXRFQ29sbGF0aW9uU3RyZW5ndGgodWNvbF9nZXRBdHRyaWJ1dGUodWNvbGxhdG9yLCBVQ09MX1NUUkVOR1RILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmludFN0YXR1cykpOwp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRTdHJlbmd0aChFQ29sbGF0aW9uU3RyZW5ndGggbmV3U3RyZW5ndGgpCnsKICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICBVQ29sbGF0aW9uU3RyZW5ndGggc3RyZW5ndGggPSBnZXRVQ29sbGF0aW9uU3RyZW5ndGgobmV3U3RyZW5ndGgpOwogIHVjb2xfc2V0QXR0cmlidXRlKHVjb2xsYXRvciwgVUNPTF9TVFJFTkdUSCwgc3RyZW5ndGgsICZpbnRTdGF0dXMpOwp9CgovKioKKiBDcmVhdGUgYSBoYXNoIGNvZGUgZm9yIHRoaXMgY29sbGF0aW9uLiBKdXN0IGhhc2ggdGhlIG1haW4gcnVsZSB0YWJsZSAtLSB0aGF0Ciogc2hvdWxkIGJlIGdvb2QgZW5vdWdoIGZvciBhbG1vc3QgYW55IHVzZS4KKi8KaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6aGFzaENvZGUoKSBjb25zdAp7CiAgaW50MzJfdCBsZW5ndGg7CiAgY29uc3QgVUNoYXIgKnJ1bGVzID0gdWNvbF9nZXRSdWxlcyh1Y29sbGF0b3IsICZsZW5ndGgpOwogIHJldHVybiB1aGFzaF9oYXNoVUNoYXJzTihydWxlcywgbGVuZ3RoKTsKfQoKLyoqCiogU2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIENvbGxhdG9yIG9iamVjdC4gc3VjY2VzcyBpcyBlcXVhbCB0bwoqIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpZiBlcnJvciBvY2N1cnMuCiogQHBhcmFtIHRoZSBuZXcgZGVjb21wb3NpdGlvbiBtb2RlCiogQHNlZSBDb2xsYXRvciNnZXREZWNvbXBvc2l0aW9uCiovCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldERlY29tcG9zaXRpb24oTm9ybWFsaXplcjo6RU1vZGUgIG1vZGUpCnsKICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICB1Y29sX3NldE5vcm1hbGl6YXRpb24odWNvbGxhdG9yLCBOb3JtYWxpemVyOjpnZXRVTm9ybWFsaXphdGlvbk1vZGUobW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKSk7Cn0KCi8qKgoqIEdldCB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIG9mIHRoZSBDb2xsYXRvciBvYmplY3QuCiogQHJldHVybiB0aGUgZGVjb21wb3NpdGlvbiBtb2RlCiogQHNlZSBDb2xsYXRvciNzZXREZWNvbXBvc2l0aW9uCiovCk5vcm1hbGl6ZXI6OkVNb2RlIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXREZWNvbXBvc2l0aW9uKHZvaWQpIGNvbnN0CnsKICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICByZXR1cm4gTm9ybWFsaXplcjo6Z2V0Tm9ybWFsaXplckVNb2RlKHVjb2xfZ2V0Tm9ybWFsaXphdGlvbih1Y29sbGF0b3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7Cn0KCi8vIFJ1bGVCYXNlQ29sbGF0b3JOZXcgcHJpdmF0ZSBjb25zdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoKSA6IGRhdGFJc093bmVkKEZBTFNFKSwgdWNvbGxhdG9yKDApCnsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKFVDb2xsYXRvciAqY29sbGF0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nICpydWxlKSA6IGRhdGFJc093bmVkKEZBTFNFKQp7CiAgdWNvbGxhdG9yID0gY29sbGF0b3I7CiAgdXJ1bGVzdHJpbmcgPSBydWxlOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhSXNPd25lZChGQUxTRSksIHVjb2xsYXRvcigwKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwoKICAvKgogIFRyeSB0byBsb2FkLCBpbiBvcmRlcjoKICAgMS4gVGhlIGRlc2lyZWQgbG9jYWxlJ3MgY29sbGF0aW9uLgogICAyLiBBIGZhbGxiYWNrIG9mIHRoZSBkZXNpcmVkIGxvY2FsZS4KICAgMy4gVGhlIGRlZmF1bHQgbG9jYWxlJ3MgY29sbGF0aW9uLgogICA0LiBBIGZhbGxiYWNrIG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4KICAgNS4gVGhlIGRlZmF1bHQgY29sbGF0aW9uIHJ1bGVzLCB3aGljaCBjb250YWlucyBlbl9VUyBjb2xsYXRpb24gcnVsZXMuCgogICBUbyByZWl0ZXJhdGUsIHdlIHRyeToKICAgU3BlY2lmaWM6CiAgICBsYW5ndWFnZStjb3VudHJ5K3ZhcmlhbnQKICAgIGxhbmd1YWdlK2NvdW50cnkKICAgIGxhbmd1YWdlCiAgIERlZmF1bHQ6CiAgICBsYW5ndWFnZStjb3VudHJ5K3ZhcmlhbnQKICAgIGxhbmd1YWdlK2NvdW50cnkKICAgIGxhbmd1YWdlCiAgIFJvb3Q6IChha2EgREVGQVVMVFJVTEVTKQogICBzdGVwcyAxLTUgYXJlIGhhbmRsZWQgYnkgcmVzb3VyY2UgYnVuZGxlIGZhbGxiYWNrIG1lY2hhbmlzbS4KICAgaG93ZXZlciwgaW4gYSB2ZXJ5IHVucHJvYmFibGUgc2l0dWF0aW9uIHRoYXQgbm8gcmVzb3VyY2UgYnVuZGxlCiAgIGRhdGEgZXhpc3RzLCBzdGVwIDUgaXMgcmVwZWF0ZWQgd2l0aCBoYXJkY29kZWQgZGVmYXVsdCBydWxlcy4KICAqLwoKICBzZXRVQ29sbGF0b3IoZGVzaXJlZExvY2FsZSwgc3RhdHVzKTsKCiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogIHsKICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICBzZXRVQ29sbGF0b3IoUmVzb3VyY2VCdW5kbGU6OmtEZWZhdWx0RmlsZW5hbWUsIHN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICAgIGlmIChzdGF0dXMgPT0gVV9aRVJPX0VSUk9SKQogICAgICAgIHN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKCiAgICAgIGlmIChzdGF0dXMgPT0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUikKICAgICAgICByZXR1cm47CiAgICB9CiAgfQoKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgewogICAgaW50MzJfdCBsZW5ndGg7CiAgICBjb25zdCBVQ2hhciAqciA9IHVjb2xfZ2V0UnVsZXModWNvbGxhdG9yLCAmbGVuZ3RoKTsKICAgIGlmIChsZW5ndGggPiAwKSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZyhyLCBsZW5ndGgpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgdXJ1bGVzdHJpbmcgPSBuZXcgVW5pY29kZVN0cmluZygpOwogICAgfQogICAgZGF0YUlzT3duZWQgPSBUUlVFOwogIH0KCiAgcmV0dXJuOwp9CgovKiBSdWxlQmFzZWRDb2xsYXRvciBwcml2YXRlIGRhdGEgbWVtYmVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyogbmVlZCBsb29rIHVwIGluIC5jb21taXQoKSAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpDSEFSSU5ERVggPSAweDcwMDAwMDAwOwovKiBFeHBhbmQgaW5kZXggZm9sbG93cyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpFWFBBTkRDSEFSSU5ERVggPSAweDdFMDAwMDAwOwovKiBjb250cmFjdCBpbmRleGVzIGZvbGxvd3MgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Q09OVFJBQ1RDSEFSSU5ERVggPSAweDdGMDAwMDAwOwovKiB1bm1hcHBlZCBjaGFyYWN0ZXIgdmFsdWVzICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEID0gMHhGRkZGRkZGRjsKLyogcHJpbWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAxMDAwMDsKLyogc2Vjb25kYXJ5IHN0cmVuZ3RoIGluY3JlbWVudCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUklOQ1JFTUVOVCA9IDB4MDAwMDAxMDA7Ci8qIHRlcnRpYXJ5IHN0cmVuZ3RoIGluY3JlbWVudCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAwMDAwMTsKLyogbWFzayBvZmYgYW55dGhpbmcgYnV0IHByaW1hcnkgb3JkZXIgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSTUFTSyA9IDB4ZmZmZjAwMDA7Ci8qIG1hc2sgb2ZmIGFueXRoaW5nIGJ1dCBzZWNvbmRhcnkgb3JkZXIgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJNQVNLID0gMHgwMDAwZmYwMDsKLyogbWFzayBvZmYgYW55dGhpbmcgYnV0IHRlcnRpYXJ5IG9yZGVyICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJNQVNLID0gMHgwMDAwMDBmZjsKLyogbWFzayBvZmYgaWdub3JhYmxlIGNoYXIgb3JkZXIgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6SUdOT1JBQkxFTUFTSyA9IDB4MDAwMGZmZmY7Ci8qIHVzZSBvbmx5IHRoZSBwcmltYXJ5IGRpZmZlcmVuY2UgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWURJRkZFUkVOQ0VPTkxZID0gMHhmZmZmMDAwMDsKLyogdXNlIG9ubHkgdGhlIHByaW1hcnkgYW5kIHNlY29uZGFyeSBkaWZmZXJlbmNlICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWURJRkZFUkVOQ0VPTkxZID0gMHhmZmZmZmYwMDsKLyogcHJpbWFyeSBvcmRlciBzaGlmdCAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJTSElGVCA9IDE2OwovKiBzZWNvbmRhcnkgb3JkZXIgc2hpZnQgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJTSElGVCA9IDg7Ci8qIHN0YXJ0aW5nIHZhbHVlIGZvciBjb2xsYXRpb24gZWxlbWVudHMgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Q09MRUxFTUVOVFNUQVJUID0gMHgwMjAyMDIwMjsKLyogdGVzdGluZyBtYXNrIGZvciBwcmltYXJ5IGxvdyBlbGVtZW50ICovCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllMT1daRVJPTUFTSyA9IDB4MDBGRjAwMDA7Ci8qIHJlc2V0aW5nIHZhbHVlIGZvciBzZWNvbmRhcmllcyBhbmQgdGVydGlhcmllcyAqLwpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpSRVNFVFNFQ09OREFSWVRFUlRJQVJZID0gMHgwMDAwMDIwMjsKLyogcmVzZXRpbmcgdmFsdWUgZm9yIHRlcnRpYXJpZXMgKi8KY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UkVTRVRURVJUSUFSWSA9IDB4MDAwMDAwMDI7Cgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNSUdOT1JBQkxFID0gMHgwMjAyOwoKLyogdW5pcXVlIGZpbGUgaWQgZm9yIHBhcml0eSBjaGVjayAqLwpjb25zdCBpbnQxNl90IFJ1bGVCYXNlZENvbGxhdG9yOjpGSUxFSUQgPSAweDU0NDM7Ci8qIGJpbmFyeSBjb2xsYXRpb24gZmlsZSBleHRlbnNpb24gKi8KY29uc3QgY2hhciogUnVsZUJhc2VkQ29sbGF0b3I6OmtGaWxlbmFtZVN1ZmZpeCA9ICIuY29sIjsKLyogY2xhc3MgaWQgPyBWYWx1ZSBpcyBpcnJlbGV2YW50ICovCmNoYXIgIFJ1bGVCYXNlZENvbGxhdG9yOjpmZ0NsYXNzSUQgPSAwOwoKLyogb3RoZXIgbWV0aG9kcyBub3QgYmVsb25naW5nIHRvIGFueSBjbGFzc2VzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KClVfQ0FQSSBVQ2hhciBmb3J3YXJkQ2hhckl0ZXJhdG9yR2x1ZSh2b2lkICppdGVyYXRvcikKewogIEZvcndhcmRDaGFyYWN0ZXJJdGVyYXRvciAqaXRlciA9ICgoRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yICopaXRlcmF0b3IpOwogIFVDaGFyIHJlc3VsdCA9IGl0ZXItPm5leHRQb3N0SW5jKCk7CiAgaWYgKHJlc3VsdCA9PSBGb3J3YXJkQ2hhcmFjdGVySXRlcmF0b3I6OkRPTkUpCiAgICByZXR1cm4gMHhGRkZGOwogIGVsc2UKICAgIHJldHVybiByZXN1bHQ7Cn0K