LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNjZmcuYyx2IDEuMjMgMjAwMi8wOC8zMSAyMjoxNzozMiBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKCiNpZiBkZWZpbmVkIChfV0lOMzIpICYmIChkZWZpbmVkIChQSUMpIHx8IGRlZmluZWQgKERMTF9FWFBPUlQpKQojZGVmaW5lIFNUUklDVAojaW5jbHVkZSA8d2luZG93cy5oPgojdW5kZWYgU1RSSUNUCiNlbmRpZgoKRmNDb25maWcgICAgKl9mY0NvbmZpZzsKCkZjQ29uZmlnICoKRmNDb25maWdDcmVhdGUgKHZvaWQpCnsKICAgIEZjU2V0TmFtZQlzZXQ7CiAgICBGY0NvbmZpZwkqY29uZmlnOwoKICAgIGNvbmZpZyA9IG1hbGxvYyAoc2l6ZW9mIChGY0NvbmZpZykpOwogICAgaWYgKCFjb25maWcpCglnb3RvIGJhaWwwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX0NPTkZJRywgc2l6ZW9mIChGY0NvbmZpZykpOwogICAgCiAgICBjb25maWctPmNvbmZpZ0RpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghY29uZmlnLT5jb25maWdEaXJzKQoJZ290byBiYWlsMTsKICAgIAogICAgY29uZmlnLT5jb25maWdGaWxlcyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFjb25maWctPmNvbmZpZ0ZpbGVzKQoJZ290byBiYWlsMjsKICAgIAogICAgY29uZmlnLT5mb250RGlycyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFjb25maWctPmZvbnREaXJzKQoJZ290byBiYWlsMzsKICAgIAogICAgY29uZmlnLT5jYWNoZSA9IDA7CiAgICBpZiAoRmNDb25maWdIb21lKCkpCglpZiAoIUZjQ29uZmlnU2V0Q2FjaGUgKGNvbmZpZywgKEZjQ2hhcjggKikgKCJ+LyIgRkNfVVNFUl9DQUNIRV9GSUxFKSkpCgkgICAgZ290byBiYWlsNDsKCiNpZmRlZiBfV0lOMzIKICAgIGlmIChjb25maWctPmNhY2hlID09IDApCiAgICB7CgkvKiBJZiBubyBob21lLCB1c2UgdGhlIHRlbXAgZm9sZGVyLiAqLwoJRmNDaGFyOAkgICAgZHVtbXlbMV07CglpbnQJICAgIHRlbXBsZW4gPSBHZXRUZW1wUGF0aCAoMSwgZHVtbXkpOwoJRmNDaGFyOCAgICAgKnRlbXAgPSBtYWxsb2MgKHRlbXBsZW4gKyAxKTsKCglpZiAodGVtcCkKCXsKCSAgICBGY0NoYXI4ICpjYWNoZV9kaXI7CgoJICAgIEdldFRlbXBQYXRoICh0ZW1wbGVuICsgMSwgdGVtcCk7CgkgICAgY2FjaGVfZGlyID0gRmNTdHJQbHVzICh0ZW1wLCBGQ19VU0VSX0NBQ0hFX0ZJTEUpOwoJICAgIGZyZWUgKHRlbXApOwoJICAgIGlmICghRmNDb25maWdTZXRDYWNoZSAoY29uZmlnLCBjYWNoZV9kaXIpKQoJICAgIHsKCQlGY1N0ckZyZWUgKGNhY2hlX2Rpcik7CgkJZ290byBiYWlsNDsKCSAgICB9CgkgICAgRmNTdHJGcmVlIChjYWNoZV9kaXIpOwoJfQogICAgfQojZW5kaWYKCiAgICBjb25maWctPmJsYW5rcyA9IDA7CgogICAgY29uZmlnLT5zdWJzdFBhdHRlcm4gPSAwOwogICAgY29uZmlnLT5zdWJzdEZvbnQgPSAwOwogICAgY29uZmlnLT5tYXhPYmplY3RzID0gMDsKICAgIGZvciAoc2V0ID0gRmNTZXRTeXN0ZW07IHNldCA8PSBGY1NldEFwcGxpY2F0aW9uOyBzZXQrKykKCWNvbmZpZy0+Zm9udHNbc2V0XSA9IDA7CgogICAgY29uZmlnLT5yZXNjYW5UaW1lID0gdGltZSgwKTsKICAgIGNvbmZpZy0+cmVzY2FuSW50ZXJ2YWwgPSAzMDsgICAgCiAgICAKICAgIHJldHVybiBjb25maWc7CgpiYWlsNDoKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5mb250RGlycyk7CmJhaWwzOgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmNvbmZpZ0ZpbGVzKTsKYmFpbDI6CiAgICBGY1N0clNldERlc3Ryb3kgKGNvbmZpZy0+Y29uZmlnRGlycyk7CmJhaWwxOgogICAgZnJlZSAoY29uZmlnKTsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0NPTkZJRywgc2l6ZW9mIChGY0NvbmZpZykpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNGaWxlVGltZSB7CiAgICB0aW1lX3QgIHRpbWU7CiAgICBGY0Jvb2wgIHNldDsKfSBGY0ZpbGVUaW1lOwoKc3RhdGljIEZjRmlsZVRpbWUKRmNDb25maWdOZXdlc3RGaWxlIChGY1N0clNldCAqZmlsZXMpCnsKICAgIEZjU3RyTGlzdAkgICAgKmxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGZpbGVzKTsKICAgIEZjRmlsZVRpbWUJICAgIG5ld2VzdCA9IHsgMCwgRmNGYWxzZSB9OwogICAgRmNDaGFyOAkgICAgKmZpbGU7CiAgICBzdHJ1Y3QgIHN0YXQgICAgc3RhdGI7CgogICAgaWYgKGxpc3QpCiAgICB7Cgl3aGlsZSAoKGZpbGUgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgkgICAgaWYgKHN0YXQgKChjaGFyICopIGZpbGUsICZzdGF0YikgPT0gMCkKCQlpZiAoIW5ld2VzdC5zZXQgfHwgc3RhdGIuc3RfbXRpbWUgLSBuZXdlc3QudGltZSA+IDApCgkJICAgIG5ld2VzdC50aW1lID0gc3RhdGIuc3RfbXRpbWU7CglGY1N0ckxpc3REb25lIChsaXN0KTsKICAgIH0KICAgIHJldHVybiBuZXdlc3Q7Cn0KCkZjQm9vbApGY0NvbmZpZ1VwdG9EYXRlIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY0ZpbGVUaW1lCWNvbmZpZ190aW1lLCBmb250X3RpbWU7CiAgICB0aW1lX3QJbm93ID0gdGltZSgwKTsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBjb25maWdfdGltZSA9IEZjQ29uZmlnTmV3ZXN0RmlsZSAoY29uZmlnLT5jb25maWdGaWxlcyk7CiAgICBmb250X3RpbWUgPSBGY0NvbmZpZ05ld2VzdEZpbGUgKGNvbmZpZy0+Y29uZmlnRGlycyk7CiAgICBpZiAoKGNvbmZpZ190aW1lLnNldCAmJiBjb25maWdfdGltZS50aW1lIC0gY29uZmlnLT5yZXNjYW5UaW1lID4gMCkgfHwKCShmb250X3RpbWUuc2V0ICYmIGZvbnRfdGltZS50aW1lIC0gY29uZmlnLT5yZXNjYW5UaW1lKSA+IDApCiAgICB7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGNvbmZpZy0+cmVzY2FuVGltZSA9IG5vdzsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyB2b2lkCkZjU3Vic3REZXN0cm95IChGY1N1YnN0ICpzKQp7CiAgICBGY1N1YnN0ICpuOwogICAgCiAgICB3aGlsZSAocykKICAgIHsKCW4gPSBzLT5uZXh0OwoJaWYgKHMtPnRlc3QpCgkgICAgRmNUZXN0RGVzdHJveSAocy0+dGVzdCk7CglpZiAocy0+ZWRpdCkKCSAgICBGY0VkaXREZXN0cm95IChzLT5lZGl0KTsKCXMgPSBuOwogICAgfQp9Cgp2b2lkCkZjQ29uZmlnRGVzdHJveSAoRmNDb25maWcgKmNvbmZpZykKewogICAgRmNTZXROYW1lCXNldDsKCiAgICBpZiAoY29uZmlnID09IF9mY0NvbmZpZykKCV9mY0NvbmZpZyA9IDA7CgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmNvbmZpZ0RpcnMpOwogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmZvbnREaXJzKTsKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5jb25maWdGaWxlcyk7CgogICAgaWYgKGNvbmZpZy0+Y2FjaGUpCglGY1N0ckZyZWUgKGNvbmZpZy0+Y2FjaGUpOwoKICAgIEZjU3Vic3REZXN0cm95IChjb25maWctPnN1YnN0UGF0dGVybik7CiAgICBGY1N1YnN0RGVzdHJveSAoY29uZmlnLT5zdWJzdEZvbnQpOwogICAgZm9yIChzZXQgPSBGY1NldFN5c3RlbTsgc2V0IDw9IEZjU2V0QXBwbGljYXRpb247IHNldCsrKQoJaWYgKGNvbmZpZy0+Zm9udHNbc2V0XSkKCSAgICBGY0ZvbnRTZXREZXN0cm95IChjb25maWctPmZvbnRzW3NldF0pOwogICAgZnJlZSAoY29uZmlnKTsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0NPTkZJRywgc2l6ZW9mIChGY0NvbmZpZykpOwp9CgovKgogKiBTY2FuIHRoZSBjdXJyZW50IGxpc3Qgb2YgZGlyZWN0b3JpZXMgaW4gdGhlIGNvbmZpZ3VyYXRpb24KICogYW5kIGJ1aWxkIHRoZSBzZXQgb2YgYXZhaWxhYmxlIGZvbnRzLiBVcGRhdGUgdGhlCiAqIHBlci11c2VyIGNhY2hlIGZpbGUgdG8gcmVmbGVjdCB0aGUgbmV3IGNvbmZpZ3VyYXRpb24KICovCgpGY0Jvb2wKRmNDb25maWdCdWlsZEZvbnRzIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY0ZvbnRTZXQJICAgICpmb250czsKICAgIEZjR2xvYmFsQ2FjaGUgICAqY2FjaGU7CiAgICBGY1N0ckxpc3QJICAgICpsaXN0OwogICAgRmNDaGFyOAkgICAgKmRpcjsKCiAgICBmb250cyA9IEZjRm9udFNldENyZWF0ZSAoKTsKICAgIGlmICghZm9udHMpCglnb3RvIGJhaWwwOwogICAgCiAgICBjYWNoZSA9IEZjR2xvYmFsQ2FjaGVDcmVhdGUgKCk7CiAgICBpZiAoIWNhY2hlKQoJZ290byBiYWlsMTsKCiAgICBpZiAoY29uZmlnLT5jYWNoZSkKCUZjR2xvYmFsQ2FjaGVMb2FkIChjYWNoZSwgY29uZmlnLT5jYWNoZSk7CgogICAgbGlzdCA9IEZjQ29uZmlnR2V0Rm9udERpcnMgKGNvbmZpZyk7CiAgICBpZiAoIWxpc3QpCglnb3RvIGJhaWwxOwoKICAgIHdoaWxlICgoZGlyID0gRmNTdHJMaXN0TmV4dCAobGlzdCkpKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRk9OVFNFVCkKCSAgICBwcmludGYgKCJzY2FuIGRpciAlc1xuIiwgZGlyKTsKCUZjRGlyU2NhbiAoZm9udHMsIGNvbmZpZy0+Zm9udERpcnMsIGNhY2hlLCBjb25maWctPmJsYW5rcywgZGlyLCBGY0ZhbHNlKTsKICAgIH0KICAgIAogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICAKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0ZPTlRTRVQpCglGY0ZvbnRTZXRQcmludCAoZm9udHMpOwoKICAgIGlmIChjb25maWctPmNhY2hlKQoJRmNHbG9iYWxDYWNoZVNhdmUgKGNhY2hlLCBjb25maWctPmNhY2hlKTsKICAgIEZjR2xvYmFsQ2FjaGVEZXN0cm95IChjYWNoZSk7CgogICAgRmNDb25maWdTZXRGb250cyAoY29uZmlnLCBmb250cywgRmNTZXRTeXN0ZW0pOwogICAgCiAgICByZXR1cm4gRmNUcnVlOwpiYWlsMToKICAgIEZjRm9udFNldERlc3Ryb3kgKGZvbnRzKTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNCb29sCkZjQ29uZmlnU2V0Q3VycmVudCAoRmNDb25maWcgKmNvbmZpZykKewogICAgaWYgKCFjb25maWctPmZvbnRzKQoJaWYgKCFGY0NvbmZpZ0J1aWxkRm9udHMgKGNvbmZpZykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CgogICAgaWYgKF9mY0NvbmZpZykKCUZjQ29uZmlnRGVzdHJveSAoX2ZjQ29uZmlnKTsKICAgIF9mY0NvbmZpZyA9IGNvbmZpZzsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQ29uZmlnICoKRmNDb25maWdHZXRDdXJyZW50ICh2b2lkKQp7CiAgICBpZiAoIV9mY0NvbmZpZykKCWlmICghRmNJbml0ICgpKQoJICAgIHJldHVybiAwOwogICAgcmV0dXJuIF9mY0NvbmZpZzsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQ29uZmlnRGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICBjb25zdCBGY0NoYXI4ICpkKQp7CiAgICByZXR1cm4gRmNTdHJTZXRBZGRGaWxlbmFtZSAoY29uZmlnLT5jb25maWdEaXJzLCBkKTsKfQoKRmNTdHJMaXN0ICoKRmNDb25maWdHZXRDb25maWdEaXJzIChGY0NvbmZpZyAgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gRmNTdHJMaXN0Q3JlYXRlIChjb25maWctPmNvbmZpZ0RpcnMpOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRGb250RGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgY29uc3QgRmNDaGFyOCAgICpkKQp7CiAgICByZXR1cm4gRmNTdHJTZXRBZGRGaWxlbmFtZSAoY29uZmlnLT5mb250RGlycywgZCk7Cn0KCkZjQm9vbApGY0NvbmZpZ0FkZERpciAoRmNDb25maWcJICAgICpjb25maWcsCgkJY29uc3QgRmNDaGFyOAkgICAgKmQpCnsKICAgIHJldHVybiAoRmNDb25maWdBZGRDb25maWdEaXIgKGNvbmZpZywgZCkgJiYgCgkgICAgRmNDb25maWdBZGRGb250RGlyIChjb25maWcsIGQpKTsKfQoKRmNTdHJMaXN0ICoKRmNDb25maWdHZXRGb250RGlycyAoRmNDb25maWcJKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBGY1N0ckxpc3RDcmVhdGUgKGNvbmZpZy0+Zm9udERpcnMpOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRDb25maWdGaWxlIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICAgY29uc3QgRmNDaGFyOCAgICpmKQp7CiAgICBGY0Jvb2wJcmV0OwogICAgRmNDaGFyOAkqZmlsZSA9IEZjQ29uZmlnRmlsZW5hbWUgKGYpOwogICAgCiAgICBpZiAoIWZpbGUpCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgcmV0ID0gRmNTdHJTZXRBZGQgKGNvbmZpZy0+Y29uZmlnRmlsZXMsIGZpbGUpOwogICAgRmNTdHJGcmVlIChmaWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCkZjU3RyTGlzdCAqCkZjQ29uZmlnR2V0Q29uZmlnRmlsZXMgKEZjQ29uZmlnICAgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gRmNTdHJMaXN0Q3JlYXRlIChjb25maWctPmNvbmZpZ0ZpbGVzKTsKfQoKRmNCb29sCkZjQ29uZmlnU2V0Q2FjaGUgKEZjQ29uZmlnCSpjb25maWcsCgkJICBjb25zdCBGY0NoYXI4CSpjKQp7CiAgICBGY0NoYXI4ICAgICpuZXcgPSBGY1N0ckNvcHlGaWxlbmFtZSAoYyk7CiAgICAKICAgIGlmICghbmV3KQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoY29uZmlnLT5jYWNoZSkKCUZjU3RyRnJlZSAoY29uZmlnLT5jYWNoZSk7CiAgICBjb25maWctPmNhY2hlID0gbmV3OwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNDaGFyOCAqCkZjQ29uZmlnR2V0Q2FjaGUgKEZjQ29uZmlnICAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+Y2FjaGU7Cn0KCkZjRm9udFNldCAqCkZjQ29uZmlnR2V0Rm9udHMgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY1NldE5hbWUJc2V0KQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+Zm9udHNbc2V0XTsKfQoKdm9pZApGY0NvbmZpZ1NldEZvbnRzIChGY0NvbmZpZwkqY29uZmlnLAoJCSAgRmNGb250U2V0CSpmb250cywKCQkgIEZjU2V0TmFtZQlzZXQpCnsKICAgIGlmIChjb25maWctPmZvbnRzW3NldF0pCglGY0ZvbnRTZXREZXN0cm95IChjb25maWctPmZvbnRzW3NldF0pOwogICAgY29uZmlnLT5mb250c1tzZXRdID0gZm9udHM7Cn0KCgoKRmNCbGFua3MgKgpGY0NvbmZpZ0dldEJsYW5rcyAoRmNDb25maWcJKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmJsYW5rczsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQmxhbmsgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY0NoYXIzMiAgICAJYmxhbmspCnsKICAgIEZjQmxhbmtzCSpiOwogICAgCiAgICBiID0gY29uZmlnLT5ibGFua3M7CiAgICBpZiAoIWIpCiAgICB7CgliID0gRmNCbGFua3NDcmVhdGUgKCk7CglpZiAoIWIpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoIUZjQmxhbmtzQWRkIChiLCBibGFuaykpCglyZXR1cm4gRmNGYWxzZTsKICAgIGNvbmZpZy0+YmxhbmtzID0gYjsKICAgIHJldHVybiBGY1RydWU7Cn0KCmludApGY0NvbmZpZ0dldFJlc2NhbkludmVydmFsIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+cmVzY2FuSW50ZXJ2YWw7Cn0KCkZjQm9vbApGY0NvbmZpZ1NldFJlc2NhbkludmVydmFsIChGY0NvbmZpZyAqY29uZmlnLCBpbnQgcmVzY2FuSW50ZXJ2YWwpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBjb25maWctPnJlc2NhbkludGVydmFsID0gcmVzY2FuSW50ZXJ2YWw7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRFZGl0IChGY0NvbmZpZwkqY29uZmlnLAoJCSBGY1Rlc3QJCSp0ZXN0LAoJCSBGY0VkaXQJCSplZGl0LAoJCSBGY01hdGNoS2luZAlraW5kKQp7CiAgICBGY1N1YnN0CSpzdWJzdCwgKipwcmV2OwogICAgRmNUZXN0CSp0OwogICAgaW50CQludW07CgogICAgc3Vic3QgPSAoRmNTdWJzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNTdWJzdCkpOwogICAgaWYgKCFzdWJzdCkKCXJldHVybiBGY0ZhbHNlOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1NVQlNULCBzaXplb2YgKEZjU3Vic3QpKTsKICAgIGlmIChraW5kID09IEZjTWF0Y2hQYXR0ZXJuKQoJcHJldiA9ICZjb25maWctPnN1YnN0UGF0dGVybjsKICAgIGVsc2UKCXByZXYgPSAmY29uZmlnLT5zdWJzdEZvbnQ7CiAgICBmb3IgKDsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCk7CiAgICAqcHJldiA9IHN1YnN0OwogICAgc3Vic3QtPm5leHQgPSAwOwogICAgc3Vic3QtPnRlc3QgPSB0ZXN0OwogICAgc3Vic3QtPmVkaXQgPSBlZGl0OwogICAgbnVtID0gMDsKICAgIGZvciAodCA9IHRlc3Q7IHQ7IHQgPSB0LT5uZXh0KQogICAgewoJaWYgKHQtPmtpbmQgPT0gRmNNYXRjaERlZmF1bHQpCgkgICAgdC0+a2luZCA9IGtpbmQ7CgludW0rKzsKICAgIH0KICAgIGlmIChjb25maWctPm1heE9iamVjdHMgPCBudW0pCgljb25maWctPm1heE9iamVjdHMgPSBudW07CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiQWRkIFN1YnN0ICIpOwoJRmNTdWJzdFByaW50IChzdWJzdCk7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNTdWJTdGF0ZSB7CiAgICBGY1BhdHRlcm5FbHQgICAqZWx0OwogICAgRmNWYWx1ZUxpc3QgICAgKnZhbHVlOwp9IEZjU3ViU3RhdGU7CgpzdGF0aWMgRmNWYWx1ZQpGY0NvbmZpZ1Byb21vdGUgKEZjVmFsdWUgdiwgRmNWYWx1ZSB1KQp7CiAgICBpZiAodi50eXBlID09IEZjVHlwZUludGVnZXIpCiAgICB7Cgl2LnR5cGUgPSBGY1R5cGVEb3VibGU7Cgl2LnUuZCA9IChkb3VibGUpIHYudS5pOwogICAgfQogICAgZWxzZSBpZiAodi50eXBlID09IEZjVHlwZVZvaWQgJiYgdS50eXBlID09IEZjVHlwZU1hdHJpeCkKICAgIHsKCXYudS5tID0gJkZjSWRlbnRpdHlNYXRyaXg7Cgl2LnR5cGUgPSBGY1R5cGVNYXRyaXg7CiAgICB9CiAgICBlbHNlIGlmICh2LnR5cGUgPT0gRmNUeXBlU3RyaW5nICYmIHUudHlwZSA9PSBGY1R5cGVMYW5nU2V0KQogICAgewoJdi51LmwgPSBGY0xhbmdTZXRQcm9tb3RlICh2LnUucyk7Cgl2LnR5cGUgPSBGY1R5cGVMYW5nU2V0OwogICAgfQogICAgcmV0dXJuIHY7Cn0KCkZjQm9vbApGY0NvbmZpZ0NvbXBhcmVWYWx1ZSAoY29uc3QgRmNWYWx1ZQltX28sCgkJICAgICAgRmNPcAkJb3AsCgkJICAgICAgY29uc3QgRmNWYWx1ZQl2X28pCnsKICAgIEZjVmFsdWUJbSA9IG1fbzsKICAgIEZjVmFsdWUJdiA9IHZfbzsKICAgIEZjQm9vbAlyZXQgPSBGY0ZhbHNlOwogICAgCiAgICBtID0gRmNDb25maWdQcm9tb3RlIChtLCB2KTsKICAgIHYgPSBGY0NvbmZpZ1Byb21vdGUgKHYsIG0pOwogICAgaWYgKG0udHlwZSA9PSB2LnR5cGUpIAogICAgewoJc3dpdGNoIChtLnR5cGUpIHsKCWNhc2UgRmNUeXBlSW50ZWdlcjoKCSAgICBicmVhazsJLyogRmNDb25maWdQcm9tb3RlIHByZXZlbnRzIHRoaXMgZnJvbSBoYXBwZW5pbmcgKi8KCWNhc2UgRmNUeXBlRG91YmxlOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBtLnUuZCA9PSB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCSAgICBjYXNlIEZjT3BOb3RDb250YWluczoKCQlyZXQgPSBtLnUuZCAhPSB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BMZXNzOiAgICAKCQlyZXQgPSBtLnUuZCA8IHYudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcExlc3NFcXVhbDogICAgCgkJcmV0ID0gbS51LmQgPD0gdi51LmQ7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTW9yZTogICAgCgkJcmV0ID0gbS51LmQgPiB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BNb3JlRXF1YWw6ICAgIAoJCXJldCA9IG0udS5kID49IHYudS5kOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVCb29sOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDogICAgCgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gbS51LmIgPT0gdi51LmI7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gbS51LmIgIT0gdi51LmI7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZVN0cmluZzoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6ICAgIAoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCXJldCA9IEZjU3RyQ21wSWdub3JlQ2FzZSAobS51LnMsIHYudS5zKSA9PSAwOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgoJCXJldCA9IEZjU3RyQ21wSWdub3JlQ2FzZSAobS51LnMsIHYudS5zKSAhPSAwOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVNYXRyaXg6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOgoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCXJldCA9IEZjTWF0cml4RXF1YWwgKG0udS5tLCB2LnUubSk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gIUZjTWF0cml4RXF1YWwgKG0udS5tLCB2LnUubSk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZUNoYXJTZXQ6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCS8qIG0gY29udGFpbnMgdiBpZiB2IGlzIGEgc3Vic2V0IG9mIG0gKi8KCQlyZXQgPSBGY0NoYXJTZXRJc1N1YnNldCAodi51LmMsIG0udS5jKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RDb250YWluczoKCQkvKiBtIGNvbnRhaW5zIHYgaWYgdiBpcyBhIHN1YnNldCBvZiBtICovCgkJcmV0ID0gIUZjQ2hhclNldElzU3Vic2V0ICh2LnUuYywgbS51LmMpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcEVxdWFsOgoJCXJldCA9IEZjQ2hhclNldEVxdWFsIChtLnUuYywgdi51LmMpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJCXJldCA9ICFGY0NoYXJTZXRFcXVhbCAobS51LmMsIHYudS5jKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlTGFuZ1NldDoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gRmNMYW5nU2V0Q29udGFpbnMgKHYudS5sLCBtLnUubCk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gRmNMYW5nU2V0Q29udGFpbnMgKHYudS5sLCBtLnUubCk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkJcmV0ID0gRmNMYW5nU2V0RXF1YWwgKHYudS5sLCBtLnUubCk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkJcmV0ID0gIUZjTGFuZ1NldEVxdWFsICh2LnUubCwgbS51LmwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVWb2lkOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBGY1RydWU7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZUZURmFjZToKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gbS51LmYgPT0gdi51LmY7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gbS51LmYgIT0gdi51LmY7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAob3AgPT0gRmNPcE5vdEVxdWFsIHx8IG9wID09IEZjT3BOb3RDb250YWlucykKCSAgICByZXQgPSBGY1RydWU7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKI2RlZmluZSBfRmNEb3VibGVGbG9vcihkKQkoKGludCkgKGQpKQojZGVmaW5lIF9GY0RvdWJsZUNlaWwoZCkJKChkb3VibGUpIChpbnQpIChkKSA9PSAoZCkgPyAoaW50KSAoZCkgOiAoaW50KSAoKGQpICsgMSkpCiNkZWZpbmUgRmNEb3VibGVGbG9vcihkKQkoKGQpID49IDAgPyBfRmNEb3VibGVGbG9vcihkKSA6IC1fRmNEb3VibGVDZWlsKC0oZCkpKQojZGVmaW5lIEZjRG91YmxlQ2VpbChkKQkJKChkKSA+PSAwID8gX0ZjRG91YmxlQ2VpbChkKSA6IC1fRmNEb3VibGVGbG9vcigtKGQpKSkKI2RlZmluZSBGY0RvdWJsZVJvdW5kKGQpCUZjRG91YmxlRmxvb3IgKChkKSArIDAuNSkKI2RlZmluZSBGY0RvdWJsZVRydW5jKGQpCSgoZCkgPj0gMCA/IF9GY0RvdWJsZUZsb29yIChkKSA6IC1fRmNEb3VibGVGbG9vciAoLShkKSkpCgpzdGF0aWMgRmNWYWx1ZQpGY0NvbmZpZ0V2YWx1YXRlIChGY1BhdHRlcm4gKnAsIEZjRXhwciAqZSkKewogICAgRmNWYWx1ZQl2LCB2bCwgdnI7CiAgICBGY1Jlc3VsdAlyOwogICAgRmNNYXRyaXgJKm07CiAgICAKICAgIHN3aXRjaCAoZS0+b3ApIHsKICAgIGNhc2UgRmNPcEludGVnZXI6Cgl2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJdi51LmkgPSBlLT51Lml2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcERvdWJsZToKCXYudHlwZSA9IEZjVHlwZURvdWJsZTsKCXYudS5kID0gZS0+dS5kdmFsOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BTdHJpbmc6Cgl2LnR5cGUgPSBGY1R5cGVTdHJpbmc7Cgl2LnUucyA9IGUtPnUuc3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcE1hdHJpeDoKCXYudHlwZSA9IEZjVHlwZU1hdHJpeDsKCXYudS5tID0gZS0+dS5tdmFsOwoJdiA9IEZjVmFsdWVTYXZlICh2KTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ2hhclNldDoKCXYudHlwZSA9IEZjVHlwZUNoYXJTZXQ7Cgl2LnUuYyA9IGUtPnUuY3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcEJvb2w6Cgl2LnR5cGUgPSBGY1R5cGVCb29sOwoJdi51LmIgPSBlLT51LmJ2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcEZpZWxkOgoJciA9IEZjUGF0dGVybkdldCAocCwgZS0+dS5maWVsZCwgMCwgJnYpOwoJaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDb25zdDoKCWlmIChGY05hbWVDb25zdGFudCAoZS0+dS5jb25zdGFudCwgJnYudS5pKSkKCSAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNPcFF1ZXN0OgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7CglpZiAodmwudHlwZSA9PSBGY1R5cGVCb29sKQoJewoJICAgIGlmICh2bC51LmIpCgkJdiA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5yaWdodC0+dS50cmVlLmxlZnQpOwoJICAgIGVsc2UKCQl2ID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0LT51LnRyZWUucmlnaHQpOwoJfQoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BFcXVhbDoKICAgIGNhc2UgRmNPcE5vdEVxdWFsOgogICAgY2FzZSBGY09wTGVzczoKICAgIGNhc2UgRmNPcExlc3NFcXVhbDoKICAgIGNhc2UgRmNPcE1vcmU6CiAgICBjYXNlIEZjT3BNb3JlRXF1YWw6CiAgICBjYXNlIEZjT3BDb250YWluczoKICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7Cgl2ciA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5yaWdodCk7Cgl2LnR5cGUgPSBGY1R5cGVCb29sOwoJdi51LmIgPSBGY0NvbmZpZ0NvbXBhcmVWYWx1ZSAodmwsIGUtPm9wLCB2cik7CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJRmNWYWx1ZURlc3Ryb3kgKHZyKTsKCWJyZWFrOwkKICAgIGNhc2UgRmNPcE9yOgogICAgY2FzZSBGY09wQW5kOgogICAgY2FzZSBGY09wUGx1czoKICAgIGNhc2UgRmNPcE1pbnVzOgogICAgY2FzZSBGY09wVGltZXM6CiAgICBjYXNlIEZjT3BEaXZpZGU6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCXZyID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0KTsKCXZsID0gRmNDb25maWdQcm9tb3RlICh2bCwgdnIpOwoJdnIgPSBGY0NvbmZpZ1Byb21vdGUgKHZyLCB2bCk7CglpZiAodmwudHlwZSA9PSB2ci50eXBlKQoJewoJICAgIHN3aXRjaCAodmwudHlwZSkgewoJICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BQbHVzOgkgICAKCQkgICAgdi50eXBlID0gRmNUeXBlRG91YmxlOwoJCSAgICB2LnUuZCA9IHZsLnUuZCArIHZyLnUuZDsgCgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcE1pbnVzOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CgkJICAgIHYudS5kID0gdmwudS5kIC0gdnIudS5kOyAKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wVGltZXM6CgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgKiB2ci51LmQ7IAoJCSAgICBicmVhazsKCQljYXNlIEZjT3BEaXZpZGU6CgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgLyB2ci51LmQ7IAoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOyAKCQkgICAgYnJlYWs7CgkJfQoJCWlmICh2LnR5cGUgPT0gRmNUeXBlRG91YmxlICYmCgkJICAgIHYudS5kID09IChkb3VibGUpIChpbnQpIHYudS5kKQoJCXsKCQkgICAgdi50eXBlID0gRmNUeXBlSW50ZWdlcjsKCQkgICAgdi51LmkgPSAoaW50KSB2LnUuZDsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY1R5cGVCb29sOgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BPcjoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSB2bC51LmIgfHwgdnIudS5iOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BBbmQ6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gdmwudS5iICYmIHZyLnUuYjsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsgCgkJICAgIGJyZWFrOwoJCX0KCQlicmVhazsKCSAgICBjYXNlIEZjVHlwZVN0cmluZzoKCQlzd2l0Y2ggKGUtPm9wKSB7CgkJY2FzZSBGY09wUGx1czoKCQkgICAgdi50eXBlID0gRmNUeXBlU3RyaW5nOwoJCSAgICB2LnUucyA9IEZjU3RyUGx1cyAodmwudS5zLCB2ci51LnMpOwoJCSAgICBpZiAoIXYudS5zKQoJCQl2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY1R5cGVNYXRyaXg6CgkJc3dpdGNoIChlLT5vcCkgewoJCWNhc2UgRmNPcFRpbWVzOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVNYXRyaXg7CgkJICAgIG0gPSBtYWxsb2MgKHNpemVvZiAoRmNNYXRyaXgpKTsKCQkgICAgaWYgKG0pCgkJICAgIHsKCQkJRmNNZW1BbGxvYyAoRkNfTUVNX01BVFJJWCwgc2l6ZW9mIChGY01hdHJpeCkpOwoJCQlGY01hdHJpeE11bHRpcGx5IChtLCB2bC51Lm0sIHZyLnUubSk7CgkJCXYudS5tID0gbTsKCQkgICAgfQoJCSAgICBlbHNlCgkJICAgIHsKCQkJdi50eXBlID0gRmNUeXBlVm9pZDsKCQkgICAgfQoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQl2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCWJyZWFrOwoJICAgIH0KCX0KCWVsc2UKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJRmNWYWx1ZURlc3Ryb3kgKHZsKTsKCUZjVmFsdWVEZXN0cm95ICh2cik7CglicmVhazsKICAgIGNhc2UgRmNPcE5vdDoKCXZsID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLmxlZnQpOwoJc3dpdGNoICh2bC50eXBlKSB7CgljYXNlIEZjVHlwZUJvb2w6CgkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCSAgICB2LnUuYiA9ICF2bC51LmI7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CgkgICAgYnJlYWs7Cgl9CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BGbG9vcjoKCXZsID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLmxlZnQpOwoJc3dpdGNoICh2bC50eXBlKSB7CgljYXNlIEZjVHlwZUludGVnZXI6CgkgICAgdiA9IHZsOwoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVEb3VibGU6CgkgICAgdi50eXBlID0gRmNUeXBlSW50ZWdlcjsKCSAgICB2LnUuaSA9IEZjRG91YmxlRmxvb3IgKHZsLnUuZCk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CgkgICAgYnJlYWs7Cgl9CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDZWlsOgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7Cglzd2l0Y2ggKHZsLnR5cGUpIHsKCWNhc2UgRmNUeXBlSW50ZWdlcjoKCSAgICB2ID0gdmw7CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZURvdWJsZToKCSAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJICAgIHYudS5pID0gRmNEb3VibGVDZWlsICh2bC51LmQpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJICAgIGJyZWFrOwoJfQoJRmNWYWx1ZURlc3Ryb3kgKHZsKTsKCWJyZWFrOwogICAgY2FzZSBGY09wUm91bmQ6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCXN3aXRjaCAodmwudHlwZSkgewoJY2FzZSBGY1R5cGVJbnRlZ2VyOgoJICAgIHYgPSB2bDsKCSAgICBicmVhazsKCWNhc2UgRmNUeXBlRG91YmxlOgoJICAgIHYudHlwZSA9IEZjVHlwZUludGVnZXI7CgkgICAgdi51LmkgPSBGY0RvdWJsZVJvdW5kICh2bC51LmQpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJICAgIGJyZWFrOwoJfQoJRmNWYWx1ZURlc3Ryb3kgKHZsKTsKCWJyZWFrOwogICAgY2FzZSBGY09wVHJ1bmM6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCXN3aXRjaCAodmwudHlwZSkgewoJY2FzZSBGY1R5cGVJbnRlZ2VyOgoJICAgIHYgPSB2bDsKCSAgICBicmVhazsKCWNhc2UgRmNUeXBlRG91YmxlOgoJICAgIHYudHlwZSA9IEZjVHlwZUludGVnZXI7CgkgICAgdi51LmkgPSBGY0RvdWJsZVRydW5jICh2bC51LmQpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJICAgIGJyZWFrOwoJfQoJRmNWYWx1ZURlc3Ryb3kgKHZsKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCXYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIH0KICAgIHJldHVybiB2Owp9CgpzdGF0aWMgRmNWYWx1ZUxpc3QgKgpGY0NvbmZpZ01hdGNoVmFsdWVMaXN0IChGY1BhdHRlcm4JKnAsCgkJCUZjVGVzdAkJKnQsCgkJCUZjVmFsdWVMaXN0CSp2YWx1ZXMpCnsKICAgIEZjVmFsdWVMaXN0CSAgICAqcmV0ID0gMDsKICAgIEZjRXhwcgkgICAgKmUgPSB0LT5leHByOwogICAgRmNWYWx1ZQkgICAgdmFsdWU7CiAgICBGY1ZhbHVlTGlzdAkgICAgKnY7CiAgICAKICAgIHdoaWxlIChlKQogICAgewoJaWYgKGUtPm9wID09IEZjT3BDb21tYSkKCXsKCSAgICB2YWx1ZSA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCSAgICBlID0gZS0+dS50cmVlLnJpZ2h0OwoJfQoJZWxzZQoJewoJICAgIHZhbHVlID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZSk7CgkgICAgZSA9IDA7Cgl9CgoJZm9yICh2ID0gdmFsdWVzOyB2OyB2ID0gdi0+bmV4dCkKCXsKCSAgICBpZiAoRmNDb25maWdDb21wYXJlVmFsdWUgKHYtPnZhbHVlLCB0LT5vcCwgdmFsdWUpKQoJICAgIHsKCQlpZiAoIXJldCkKCQkgICAgcmV0ID0gdjsKCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlpZiAodC0+cXVhbCA9PSBGY1F1YWxBbGwpCgkJewoJCSAgICByZXQgPSAwOwoJCSAgICBicmVhazsKCQl9CgkgICAgfQoJfQoJRmNWYWx1ZURlc3Ryb3kgKHZhbHVlKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBGY1ZhbHVlTGlzdCAqCkZjQ29uZmlnVmFsdWVzIChGY1BhdHRlcm4gKnAsIEZjRXhwciAqZSwgRmNWYWx1ZUJpbmRpbmcgYmluZGluZykKewogICAgRmNWYWx1ZUxpc3QJKmw7CiAgICAKICAgIGlmICghZSkKCXJldHVybiAwOwogICAgbCA9IChGY1ZhbHVlTGlzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIGlmICghbCkKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIGlmIChlLT5vcCA9PSBGY09wQ29tbWEpCiAgICB7CglsLT52YWx1ZSA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCWwtPm5leHQgID0gRmNDb25maWdWYWx1ZXMgKHAsIGUtPnUudHJlZS5yaWdodCwgYmluZGluZyk7CiAgICB9CiAgICBlbHNlCiAgICB7CglsLT52YWx1ZSA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUpOwoJbC0+bmV4dCAgPSAwOwogICAgfQogICAgbC0+YmluZGluZyA9IGJpbmRpbmc7CiAgICB3aGlsZSAobCAmJiBsLT52YWx1ZS50eXBlID09IEZjVHlwZVZvaWQpCiAgICB7CglGY1ZhbHVlTGlzdAkqbmV4dCA9IGwtPm5leHQ7CgkKCUZjTWVtRnJlZSAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKCWZyZWUgKGwpOwoJbCA9IG5leHQ7CiAgICB9CiAgICByZXR1cm4gbDsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ0FkZCAoRmNWYWx1ZUxpc3QgICAgKipoZWFkLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqcG9zaXRpb24sCgkgICAgIEZjQm9vbAkgICAgYXBwZW5kLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqbmV3KQp7CiAgICBGY1ZhbHVlTGlzdAkgICAgKipwcmV2LCAqbGFzdCwgKnY7CiAgICBGY1ZhbHVlQmluZGluZyAgc2FtZUJpbmRpbmc7CiAgICAKICAgIGlmIChwb3NpdGlvbikKCXNhbWVCaW5kaW5nID0gcG9zaXRpb24tPmJpbmRpbmc7CiAgICBlbHNlCglzYW1lQmluZGluZyA9IEZjVmFsdWVCaW5kaW5nV2VhazsKICAgIGZvciAodiA9IG5ldzsgdjsgdiA9IHYtPm5leHQpCglpZiAodi0+YmluZGluZyA9PSBGY1ZhbHVlQmluZGluZ1NhbWUpCgkgICAgdi0+YmluZGluZyA9IHNhbWVCaW5kaW5nOwogICAgaWYgKGFwcGVuZCkKICAgIHsKCWlmIChwb3NpdGlvbikKCSAgICBwcmV2ID0gJnBvc2l0aW9uLT5uZXh0OwoJZWxzZQoJICAgIGZvciAocHJldiA9IGhlYWQ7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpCgkJOwogICAgfQogICAgZWxzZQogICAgewoJaWYgKHBvc2l0aW9uKQoJewoJICAgIGZvciAocHJldiA9IGhlYWQ7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpCgkgICAgewoJCWlmICgqcHJldiA9PSBwb3NpdGlvbikKCQkgICAgYnJlYWs7CgkgICAgfQoJfQoJZWxzZQoJICAgIHByZXYgPSBoZWFkOwoKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgl7CgkgICAgaWYgKCEqcHJldikKCQlwcmludGYgKCJwb3NpdGlvbiBub3Qgb24gbGlzdFxuIik7Cgl9CiAgICB9CgogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIiVzIGxpc3QgYmVmb3JlICIsIGFwcGVuZCA/ICJBcHBlbmQiIDogIlByZXBlbmQiKTsKCUZjVmFsdWVMaXN0UHJpbnQgKCpoZWFkKTsKCXByaW50ZiAoIlxuIik7CiAgICB9CiAgICAKICAgIGlmIChuZXcpCiAgICB7CglsYXN0ID0gbmV3OwoJd2hpbGUgKGxhc3QtPm5leHQpCgkgICAgbGFzdCA9IGxhc3QtPm5leHQ7CiAgICAKCWxhc3QtPm5leHQgPSAqcHJldjsKCSpwcmV2ID0gbmV3OwogICAgfQogICAgCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiJXMgbGlzdCBhZnRlciAiLCBhcHBlbmQgPyAiQXBwZW5kIiA6ICJQcmVwZW5kIik7CglGY1ZhbHVlTGlzdFByaW50ICgqaGVhZCk7CglwcmludGYgKCJcbiIpOwogICAgfQogICAgCiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgdm9pZApGY0NvbmZpZ0RlbCAoRmNWYWx1ZUxpc3QgICAgKipoZWFkLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqcG9zaXRpb24pCnsKICAgIEZjVmFsdWVMaXN0ICAgICoqcHJldjsKCiAgICBmb3IgKHByZXYgPSBoZWFkOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KQogICAgewoJaWYgKCpwcmV2ID09IHBvc2l0aW9uKQoJewoJICAgICpwcmV2ID0gcG9zaXRpb24tPm5leHQ7CgkgICAgcG9zaXRpb24tPm5leHQgPSAwOwoJICAgIEZjVmFsdWVMaXN0RGVzdHJveSAocG9zaXRpb24pOwoJICAgIGJyZWFrOwoJfQogICAgfQp9CgpzdGF0aWMgdm9pZApGY0NvbmZpZ1BhdHRlcm5BZGQgKEZjUGF0dGVybgkqcCwKCQkgICAgY29uc3QgY2hhcgkqb2JqZWN0LAoJCSAgICBGY1ZhbHVlTGlzdAkqbGlzdCwKCQkgICAgRmNCb29sCWFwcGVuZCkKewogICAgaWYgKGxpc3QpCiAgICB7CglGY1BhdHRlcm5FbHQgICAgKmUgPSBGY1BhdHRlcm5JbnNlcnRFbHQgKHAsIG9iamVjdCk7CiAgICAKCWlmICghZSkKCSAgICByZXR1cm47CglGY0NvbmZpZ0FkZCAoJmUtPnZhbHVlcywgMCwgYXBwZW5kLCBsaXN0KTsKICAgIH0KfQoKLyoKICogRGVsZXRlIGFsbCB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGEgZmllbGQKICovCnN0YXRpYyB2b2lkCkZjQ29uZmlnUGF0dGVybkRlbCAoRmNQYXR0ZXJuCSpwLAoJCSAgICBjb25zdCBjaGFyCSpvYmplY3QpCnsKICAgIEZjUGF0dGVybkVsdCAgICAqZSA9IEZjUGF0dGVybkZpbmRFbHQgKHAsIG9iamVjdCk7CiAgICBpZiAoIWUpCglyZXR1cm47CiAgICB3aGlsZSAoZS0+dmFsdWVzKQoJRmNDb25maWdEZWwgKCZlLT52YWx1ZXMsIGUtPnZhbHVlcyk7Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnUGF0dGVybkNhbm9uIChGY1BhdHRlcm4JICAgICpwLAoJCSAgICAgIGNvbnN0IGNoYXIgICAgKm9iamVjdCkKewogICAgRmNQYXR0ZXJuRWx0ICAgICplID0gRmNQYXR0ZXJuRmluZEVsdCAocCwgb2JqZWN0KTsKICAgIGlmICghZSkKCXJldHVybjsKICAgIGlmICghZS0+dmFsdWVzKQoJRmNQYXR0ZXJuRGVsIChwLCBvYmplY3QpOwp9CgpGY0Jvb2wKRmNDb25maWdTdWJzdGl0dXRlV2l0aFBhdCAoRmNDb25maWcgICAgKmNvbmZpZywKCQkJICAgRmNQYXR0ZXJuICAgKnAsCgkJCSAgIEZjUGF0dGVybiAgICpwX3BhdCwKCQkJICAgRmNNYXRjaEtpbmQga2luZCkKewogICAgRmNTdWJzdAkgICAgKnM7CiAgICBGY1N1YlN0YXRlCSAgICAqc3Q7CiAgICBpbnQJCSAgICBpOwogICAgRmNUZXN0CSAgICAqdDsKICAgIEZjRWRpdAkgICAgKmU7CiAgICBGY1ZhbHVlTGlzdAkgICAgKmw7CiAgICBGY1BhdHRlcm4JICAgICptOwoKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CgogICAgc3QgPSAoRmNTdWJTdGF0ZSAqKSBtYWxsb2MgKGNvbmZpZy0+bWF4T2JqZWN0cyAqIHNpemVvZiAoRmNTdWJTdGF0ZSkpOwogICAgaWYgKCFzdCAmJiBjb25maWctPm1heE9iamVjdHMpCglyZXR1cm4gRmNGYWxzZTsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9TVUJTVEFURSwgY29uZmlnLT5tYXhPYmplY3RzICogc2l6ZW9mIChGY1N1YlN0YXRlKSk7CgogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIkZjQ29uZmlnU3Vic3RpdHV0ZSAiKTsKCUZjUGF0dGVyblByaW50IChwKTsKICAgIH0KICAgIGlmIChraW5kID09IEZjTWF0Y2hQYXR0ZXJuKQoJcyA9IGNvbmZpZy0+c3Vic3RQYXR0ZXJuOwogICAgZWxzZQoJcyA9IGNvbmZpZy0+c3Vic3RGb250OwogICAgZm9yICg7IHM7IHMgPSBzLT5uZXh0KQogICAgewoJLyoKCSAqIENoZWNrIHRoZSB0ZXN0cyB0byBzZWUgaWYKCSAqIHRoZXkgYWxsIG1hdGNoIHRoZSBwYXR0ZXJuCgkgKi8KCWZvciAodCA9IHMtPnRlc3QsIGkgPSAwOyB0OyB0ID0gdC0+bmV4dCwgaSsrKQoJewoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgkgICAgewoJCXByaW50ZiAoIkZjQ29uZmlnU3Vic3RpdHV0ZSB0ZXN0ICIpOwoJCUZjVGVzdFByaW50ICh0KTsKCSAgICB9CgkgICAgc3RbaV0uZWx0ID0gMDsKCSAgICBpZiAoa2luZCA9PSBGY01hdGNoRm9udCAmJiB0LT5raW5kID09IEZjTWF0Y2hQYXR0ZXJuKQoJCW0gPSBwX3BhdDsKCSAgICBlbHNlCgkJbSA9IHA7CgkgICAgaWYgKG0pCgkJc3RbaV0uZWx0ID0gRmNQYXR0ZXJuRmluZEVsdCAobSwgdC0+ZmllbGQpOwoJICAgIGVsc2UKCQlzdFtpXS5lbHQgPSAwOwoJICAgIC8qCgkgICAgICogSWYgdGhlcmUncyBubyBzdWNoIGZpZWxkIGluIHRoZSBmb250LAoJICAgICAqIHRoZW4gRmNRdWFsQWxsIG1hdGNoZXMgd2hpbGUgRmNRdWFsQW55IGRvZXMgbm90CgkgICAgICovCgkgICAgaWYgKCFzdFtpXS5lbHQpCgkgICAgewoJCWlmICh0LT5xdWFsID09IEZjUXVhbEFsbCkKCQl7CgkJICAgIHN0W2ldLnZhbHVlID0gMDsKCQkgICAgY29udGludWU7CgkJfQoJCWVsc2UKCQkgICAgYnJlYWs7CgkgICAgfQoJICAgIC8qCgkgICAgICogQ2hlY2sgdG8gc2VlIGlmIHRoZXJlIGlzIGEgbWF0Y2gsIG1hcmsgdGhlIGxvY2F0aW9uCgkgICAgICogdG8gYXBwbHkgbWF0Y2gtcmVsYXRpdmUgZWRpdHMKCSAgICAgKi8KCSAgICBzdFtpXS52YWx1ZSA9IEZjQ29uZmlnTWF0Y2hWYWx1ZUxpc3QgKG0sIHQsIHN0W2ldLmVsdC0+dmFsdWVzKTsKCSAgICBpZiAoIXN0W2ldLnZhbHVlKQoJCWJyZWFrOwoJICAgIGlmICh0LT5xdWFsID09IEZjUXVhbEZpcnN0ICYmIHN0W2ldLnZhbHVlICE9IHN0W2ldLmVsdC0+dmFsdWVzKQoJCWJyZWFrOwoJICAgIGlmICh0LT5xdWFsID09IEZjUXVhbE5vdEZpcnN0ICYmIHN0W2ldLnZhbHVlID09IHN0W2ldLmVsdC0+dmFsdWVzKQoJCWJyZWFrOwoJfQoJaWYgKHQpCgl7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCQlwcmludGYgKCJObyBtYXRjaFxuIik7CgkgICAgY29udGludWU7Cgl9CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJewoJICAgIHByaW50ZiAoIlN1YnN0aXR1dGUgIik7CgkgICAgRmNTdWJzdFByaW50IChzKTsKCX0KCWZvciAoZSA9IHMtPmVkaXQ7IGU7IGUgPSBlLT5uZXh0KQoJewoJICAgIC8qCgkgICAgICogRXZhbHVhdGUgdGhlIGxpc3Qgb2YgZXhwcmVzc2lvbnMKCSAgICAgKi8KCSAgICBsID0gRmNDb25maWdWYWx1ZXMgKHAsIGUtPmV4cHIsIGUtPmJpbmRpbmcpOwoJICAgIC8qCgkgICAgICogTG9jYXRlIGFueSB0ZXN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGZpZWxkLCBza2lwcGluZwoJICAgICAqIHRlc3RzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcGF0dGVybiB3aGVuIHN1YnN0aXR1dGluZyBpbgoJICAgICAqIHRoZSBmb250CgkgICAgICovCgkgICAgZm9yICh0ID0gcy0+dGVzdCwgaSA9IDA7IHQ7IHQgPSB0LT5uZXh0LCBpKyspCgkgICAgewoJCWlmICgodC0+a2luZCA9PSBGY01hdGNoRm9udCB8fCBraW5kID09IEZjTWF0Y2hQYXR0ZXJuKSAmJgoJCSAgICAhRmNTdHJDbXBJZ25vcmVDYXNlICgoRmNDaGFyOCAqKSB0LT5maWVsZCwgCgkJCQkJIChGY0NoYXI4ICopIGUtPmZpZWxkKSkKCQl7CgkJICAgIC8qIAoJCSAgICAgKiBLTFVER0UgLSB0aGUgcGF0dGVybiBtYXkgaGF2ZSBiZWVuIHJlYWxsb2NhdGVkIG9yCgkJICAgICAqIHRoaW5ncyBtYXkgaGF2ZSBiZWVuIGluc2VydGVkIG9yIGRlbGV0ZWQgYWJvdmUKCQkgICAgICogdGhpcyBlbGVtZW50IGJ5IG90aGVyIGVkaXRzLiAgR28gYmFjayBhbmQgZmluZAoJCSAgICAgKiB0aGUgZWxlbWVudCBhZ2FpbgoJCSAgICAgKi8KCQkgICAgaWYgKGUgIT0gcy0+ZWRpdCAmJiBzdFtpXS5lbHQpCgkJCXN0W2ldLmVsdCA9IEZjUGF0dGVybkZpbmRFbHQgKHAsIHQtPmZpZWxkKTsKCQkgICAgaWYgKCFzdFtpXS5lbHQpCgkJCXQgPSAwOwoJCSAgICBicmVhazsKCQl9CgkgICAgfQoJICAgIHN3aXRjaCAoZS0+b3ApIHsKCSAgICBjYXNlIEZjT3BBc3NpZ246CgkJLyoKCQkgKiBJZiB0aGVyZSB3YXMgYSB0ZXN0LCB0aGVuIHJlcGxhY2UgdGhlIG1hdGNoZWQKCQkgKiB2YWx1ZSB3aXRoIHRoZSBuZXcgbGlzdCBvZiB2YWx1ZXMKCQkgKi8KCQlpZiAodCkKCQl7CgkJICAgIEZjVmFsdWVMaXN0CSp0aGlzVmFsdWUgPSBzdFtpXS52YWx1ZTsKCQkgICAgRmNWYWx1ZUxpc3QJKm5leHRWYWx1ZSA9IHRoaXNWYWx1ZSA/IHRoaXNWYWx1ZS0+bmV4dCA6IDA7CgkJICAgIAoJCSAgICAvKgoJCSAgICAgKiBBcHBlbmQgdGhlIG5ldyBsaXN0IG9mIHZhbHVlcyBhZnRlciB0aGUgY3VycmVudCB2YWx1ZQoJCSAgICAgKi8KCQkgICAgRmNDb25maWdBZGQgKCZzdFtpXS5lbHQtPnZhbHVlcywgdGhpc1ZhbHVlLCBGY1RydWUsIGwpOwoJCSAgICAvKgoJCSAgICAgKiBEZWxldGUgdGhlIG1hcmtlZCB2YWx1ZQoJCSAgICAgKi8KCQkgICAgRmNDb25maWdEZWwgKCZzdFtpXS5lbHQtPnZhbHVlcywgdGhpc1ZhbHVlKTsKCQkgICAgLyoKCQkgICAgICogQWRqdXN0IGFueSBwb2ludGVycyBpbnRvIHRoZSB2YWx1ZSBsaXN0IHRvIGVuc3VyZQoJCSAgICAgKiBmdXR1cmUgZWRpdHMgb2NjdXIgYXQgdGhlIHNhbWUgcGxhY2UKCQkgICAgICovCgkJICAgIGZvciAodCA9IHMtPnRlc3QsIGkgPSAwOyB0OyB0ID0gdC0+bmV4dCwgaSsrKQoJCSAgICB7CgkJCWlmIChzdFtpXS52YWx1ZSA9PSB0aGlzVmFsdWUpCgkJCSAgICBzdFtpXS52YWx1ZSA9IG5leHRWYWx1ZTsKCQkgICAgfQoJCSAgICBicmVhazsKCQl9CgkJLyogZmFsbCB0aHJvdWdoIC4uLiAqLwoJICAgIGNhc2UgRmNPcEFzc2lnblJlcGxhY2U6CgkJLyoKCQkgKiBEZWxldGUgYWxsIG9mIHRoZSB2YWx1ZXMgYW5kIGluc2VydAoJCSAqIHRoZSBuZXcgc2V0CgkJICovCgkJRmNDb25maWdQYXR0ZXJuRGVsIChwLCBlLT5maWVsZCk7CgkJRmNDb25maWdQYXR0ZXJuQWRkIChwLCBlLT5maWVsZCwgbCwgRmNUcnVlKTsKCQkvKgoJCSAqIEFkanVzdCBhbnkgcG9pbnRlcnMgaW50byB0aGUgdmFsdWUgbGlzdCBhcyB0aGV5IG5vCgkJICogbG9uZ2VyIHBvaW50IHRvIGFueXRoaW5nIHZhbGlkCgkJICovCgkJaWYgKHQpCgkJewoJCSAgICBGY1BhdHRlcm5FbHQgICAgKnRoaXNFbHQgPSBzdFtpXS5lbHQ7CgkJICAgIGZvciAodCA9IHMtPnRlc3QsIGkgPSAwOyB0OyB0ID0gdC0+bmV4dCwgaSsrKQoJCSAgICB7CgkJCWlmIChzdFtpXS5lbHQgPT0gdGhpc0VsdCkKCQkJICAgIHN0W2ldLnZhbHVlID0gMDsKCQkgICAgfQoJCX0KCQlicmVhazsKCSAgICBjYXNlIEZjT3BQcmVwZW5kOgoJCWlmICh0KQoJCXsKCQkgICAgRmNDb25maWdBZGQgKCZzdFtpXS5lbHQtPnZhbHVlcywgc3RbaV0udmFsdWUsIEZjRmFsc2UsIGwpOwoJCSAgICBicmVhazsKCQl9CgkJLyogZmFsbCB0aHJvdWdoIC4uLiAqLwoJICAgIGNhc2UgRmNPcFByZXBlbmRGaXJzdDoKCQlGY0NvbmZpZ1BhdHRlcm5BZGQgKHAsIGUtPmZpZWxkLCBsLCBGY0ZhbHNlKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BBcHBlbmQ6CgkJaWYgKHQpCgkJewoJCSAgICBGY0NvbmZpZ0FkZCAoJnN0W2ldLmVsdC0+dmFsdWVzLCBzdFtpXS52YWx1ZSwgRmNUcnVlLCBsKTsKCQkgICAgYnJlYWs7CgkJfQoJCS8qIGZhbGwgdGhyb3VnaCAuLi4gKi8KCSAgICBjYXNlIEZjT3BBcHBlbmRMYXN0OgoJCUZjQ29uZmlnUGF0dGVybkFkZCAocCwgZS0+ZmllbGQsIGwsIEZjVHJ1ZSk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9Cgl9CgkvKgoJICogTm93IGdvIHRocm91Z2ggdGhlIHBhdHRlcm4gYW5kIGVsaW1pbmF0ZQoJICogYW55IHByb3BlcnRpZXMgd2l0aG91dCBkYXRhCgkgKi8KCWZvciAoZSA9IHMtPmVkaXQ7IGU7IGUgPSBlLT5uZXh0KQoJICAgIEZjQ29uZmlnUGF0dGVybkNhbm9uIChwLCBlLT5maWVsZCk7CgoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCXsKCSAgICBwcmludGYgKCJGY0NvbmZpZ1N1YnN0aXR1dGUgZWRpdCIpOwoJICAgIEZjUGF0dGVyblByaW50IChwKTsKCX0KICAgIH0KICAgIEZjTWVtRnJlZSAoRkNfTUVNX1NVQlNUQVRFLCBjb25maWctPm1heE9iamVjdHMgKiBzaXplb2YgKEZjU3ViU3RhdGUpKTsKICAgIGZyZWUgKHN0KTsKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCJGY0NvbmZpZ1N1YnN0aXR1dGUgZG9uZSIpOwoJRmNQYXR0ZXJuUHJpbnQgKHApOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjQ29uZmlnU3Vic3RpdHV0ZSAoRmNDb25maWcJKmNvbmZpZywKCQkgICAgRmNQYXR0ZXJuCSpwLAoJCSAgICBGY01hdGNoS2luZAlraW5kKQp7CiAgICByZXR1cm4gRmNDb25maWdTdWJzdGl0dXRlV2l0aFBhdCAoY29uZmlnLCBwLCAwLCBraW5kKTsKfQoKI2lmIGRlZmluZWQgKF9XSU4zMikgJiYgKGRlZmluZWQgKFBJQykgfHwgZGVmaW5lZCAoRExMX0VYUE9SVCkpCgpzdGF0aWMgRmNDaGFyOCBmb250Y29uZmlnX3BhdGhbMTAwMF0gPSAiIjsKCkJPT0wgV0lOQVBJCkRsbE1haW4gKEhJTlNUQU5DRSBoaW5zdERMTCwKCSBEV09SRCAgICAgZmR3UmVhc29uLAoJIExQVk9JRCAgICBscHZSZXNlcnZlZCkKewogIEZjQ2hhcjggKnA7CgogIHN3aXRjaCAoZmR3UmVhc29uKSB7CiAgY2FzZSBETExfUFJPQ0VTU19BVFRBQ0g6CiAgICAgIGlmICghR2V0TW9kdWxlRmlsZU5hbWUgKChITU9EVUxFKSBoaW5zdERMTCwgZm9udGNvbmZpZ19wYXRoLAoJCQkgICAgICBzaXplb2YgKGZvbnRjb25maWdfcGF0aCkpKQoJICBicmVhazsKCiAgICAgIC8qIElmIHRoZSBmb250Y29uZmlnIERMTCBpcyBpbiBhICJiaW4iIG9yICJsaWIiIHN1YmZvbGRlciwKICAgICAgICogYXNzdW1lIGl0J3MgYSBVbml4LXN0eWxlIGluc3RhbGxhdGlvbiB0cmVlLCBhbmQgdXNlCiAgICAgICAqICJldGMvZm9udHMiIGluIHRoZXJlIGFzIEZPTlRDT05GSUdfUEFUSC4gT3RoZXJ3aXNlIHVzZSB0aGUKICAgICAgICogZm9sZGVyIHdoZXJlIHRoZSBETEwgaXMgYXMgRk9OVENPTkZJR19QQVRILgogICAgICAgKi8KICAgICAgcCA9IHN0cnJjaHIgKGZvbnRjb25maWdfcGF0aCwgJ1xcJyk7CiAgICAgIGlmIChwKQogICAgICB7CgkgICpwID0gJ1wwJzsKCSAgcCA9IHN0cnJjaHIgKGZvbnRjb25maWdfcGF0aCwgJ1xcJyk7CgkgIGlmIChwICYmIChGY1N0ckNtcElnbm9yZUNhc2UgKHAgKyAxLCAiYmluIikgPT0gMCB8fAoJCSAgICBGY1N0ckNtcElnbm9yZUNhc2UgKHAgKyAxLCAibGliIikgPT0gMCkpCgkgICAgICAqcCA9ICdcMCc7CgkgIHN0cmNhdCAoZm9udGNvbmZpZ19wYXRoLCAiXFxldGNcXGZvbnRzIik7CiAgICAgIH0KICAgICAgZWxzZQogICAgICAgICAgZm9udGNvbmZpZ19wYXRoWzBdID0gJ1wwJzsKICAgICAgCiAgICAgIGJyZWFrOwogIH0KCiAgcmV0dXJuIFRSVUU7Cn0KCiN1bmRlZiBGT05UQ09ORklHX1BBVEgKI2RlZmluZSBGT05UQ09ORklHX1BBVEggZm9udGNvbmZpZ19wYXRoCgojZWxzZSAvKiAhKF9XSU4zMiAmJiBQSUMpICovCgojZW5kaWYgLyogIShfV0lOMzIgJiYgUElDKSAqLwoKI2lmbmRlZiBGT05UQ09ORklHX0ZJTEUKI2RlZmluZSBGT05UQ09ORklHX0ZJTEUJImZvbnRzLmNvbmYiCiNlbmRpZgoKc3RhdGljIEZjQ2hhcjggKgpGY0NvbmZpZ0ZpbGVFeGlzdHMgKGNvbnN0IEZjQ2hhcjggKmRpciwgY29uc3QgRmNDaGFyOCAqZmlsZSkKewogICAgRmNDaGFyOCAgICAqcGF0aDsKCiAgICBpZiAoIWRpcikKCWRpciA9IChGY0NoYXI4ICopICIiOwogICAgcGF0aCA9IG1hbGxvYyAoc3RybGVuICgoY2hhciAqKSBkaXIpICsgMSArIHN0cmxlbiAoKGNoYXIgKikgZmlsZSkgKyAxKTsKICAgIGlmICghcGF0aCkKCXJldHVybiAwOwoKICAgIHN0cmNweSAoKGNoYXIgKikgcGF0aCwgKGNvbnN0IGNoYXIgKikgZGlyKTsKICAgIC8qIG1ha2Ugc3VyZSB0aGVyZSdzIGEgc2luZ2xlIHNlcGFyYXRvciAqLwojaWZkZWYgX1dJTjMyCiAgICBpZiAoKCFwYXRoWzBdIHx8IChwYXRoW3N0cmxlbigoY2hhciAqKSBwYXRoKS0xXSAhPSAnLycgJiYKCQkgICAgICBwYXRoW3N0cmxlbigoY2hhciAqKSBwYXRoKS0xXSAhPSAnXFwnKSkgJiYKCSAoZmlsZVswXSAhPSAnLycgJiYgZmlsZVswXSAhPSAnXFwnKSkKCXN0cmNhdCAoKGNoYXIgKikgcGF0aCwgIlxcIik7CiNlbHNlCiAgICBpZiAoKCFwYXRoWzBdIHx8IHBhdGhbc3RybGVuKChjaGFyICopIHBhdGgpLTFdICE9ICcvJykgJiYgZmlsZVswXSAhPSAnLycpCglzdHJjYXQgKChjaGFyICopIHBhdGgsICIvIik7CiNlbmRpZgogICAgc3RyY2F0ICgoY2hhciAqKSBwYXRoLCAoY2hhciAqKSBmaWxlKTsKCiAgICBGY01lbUFsbG9jIChGQ19NRU1fU1RSSU5HLCBzdHJsZW4gKChjaGFyICopIHBhdGgpICsgMSk7CiAgICBpZiAoYWNjZXNzICgoY2hhciAqKSBwYXRoLCBSX09LKSA9PSAwKQoJcmV0dXJuIHBhdGg7CiAgICAKICAgIEZjU3RyRnJlZSAocGF0aCk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZjQ2hhcjggKioKRmNDb25maWdHZXRQYXRoICh2b2lkKQp7CiAgICBGY0NoYXI4ICAgICoqcGF0aDsKICAgIEZjQ2hhcjggICAgKmVudiwgKmUsICpjb2xvbjsKICAgIEZjQ2hhcjggICAgKmRpcjsKICAgIGludAkgICAgbnBhdGg7CiAgICBpbnQJICAgIGk7CgogICAgbnBhdGggPSAyOwkvKiBkZWZhdWx0IGRpciArIG51bGwgKi8KICAgIGVudiA9IChGY0NoYXI4ICopIGdldGVudiAoIkZPTlRDT05GSUdfUEFUSCIpOwogICAgaWYgKGVudikKICAgIHsKCWUgPSBlbnY7CglucGF0aCsrOwoJd2hpbGUgKCplKQoJICAgIGlmICgqZSsrID09IEZDX1NFQVJDSF9QQVRIX1NFUEFSQVRPUikKCQlucGF0aCsrOwogICAgfQogICAgcGF0aCA9IGNhbGxvYyAobnBhdGgsIHNpemVvZiAoRmNDaGFyOCAqKSk7CiAgICBpZiAoIXBhdGgpCglnb3RvIGJhaWwwOwogICAgaSA9IDA7CgogICAgaWYgKGVudikKICAgIHsKCWUgPSBlbnY7Cgl3aGlsZSAoKmUpIAoJewoJICAgIGNvbG9uID0gKEZjQ2hhcjggKikgc3RyY2hyICgoY2hhciAqKSBlLCBGQ19TRUFSQ0hfUEFUSF9TRVBBUkFUT1IpOwoJICAgIGlmICghY29sb24pCgkJY29sb24gPSBlICsgc3RybGVuICgoY2hhciAqKSBlKTsKCSAgICBwYXRoW2ldID0gbWFsbG9jIChjb2xvbiAtIGUgKyAxKTsKCSAgICBpZiAoIXBhdGhbaV0pCgkJZ290byBiYWlsMTsKCSAgICBzdHJuY3B5ICgoY2hhciAqKSBwYXRoW2ldLCAoY29uc3QgY2hhciAqKSBlLCBjb2xvbiAtIGUpOwoJICAgIHBhdGhbaV1bY29sb24gLSBlXSA9ICdcMCc7CgkgICAgaWYgKCpjb2xvbikKCQllID0gY29sb24gKyAxOwoJICAgIGVsc2UKCQllID0gY29sb247CgkgICAgaSsrOwoJfQogICAgfQogICAgCiAgICBkaXIgPSAoRmNDaGFyOCAqKSBGT05UQ09ORklHX1BBVEg7CiAgICBwYXRoW2ldID0gbWFsbG9jIChzdHJsZW4gKChjaGFyICopIGRpcikgKyAxKTsKICAgIGlmICghcGF0aFtpXSkKCWdvdG8gYmFpbDE7CiAgICBzdHJjcHkgKChjaGFyICopIHBhdGhbaV0sIChjb25zdCBjaGFyICopIGRpcik7CiAgICByZXR1cm4gcGF0aDsKCmJhaWwxOgogICAgZm9yIChpID0gMDsgcGF0aFtpXTsgaSsrKQoJZnJlZSAocGF0aFtpXSk7CiAgICBmcmVlIChwYXRoKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKRmNDb25maWdGcmVlUGF0aCAoRmNDaGFyOCAqKnBhdGgpCnsKICAgIEZjQ2hhcjggICAgKipwOwoKICAgIGZvciAocCA9IHBhdGg7ICpwOyBwKyspCglmcmVlICgqcCk7CiAgICBmcmVlIChwYXRoKTsKfQoKc3RhdGljIEZjQm9vbAlfRmNDb25maWdIb21lRW5hYmxlZCA9IEZjVHJ1ZTsKCkZjQ2hhcjggKgpGY0NvbmZpZ0hvbWUgKHZvaWQpCnsKICAgIGlmIChfRmNDb25maWdIb21lRW5hYmxlZCkKICAgIHsKICAgICAgICBjaGFyICpob21lID0gZ2V0ZW52ICgiSE9NRSIpOwoKI2lmZGVmIF9XSU4zMgoJaWYgKGhvbWUgPT0gTlVMTCkKCSAgICBob21lID0gZ2V0ZW52ICgiVVNFUlBST0ZJTEUiKTsKI2VuZGlmCgoJcmV0dXJuIGhvbWU7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKRmNCb29sCkZjQ29uZmlnRW5hYmxlSG9tZSAoRmNCb29sIGVuYWJsZSkKewogICAgRmNCb29sICBwcmV2ID0gX0ZjQ29uZmlnSG9tZUVuYWJsZWQ7CiAgICBfRmNDb25maWdIb21lRW5hYmxlZCA9IGVuYWJsZTsKICAgIHJldHVybiBwcmV2Owp9CgpGY0NoYXI4ICoKRmNDb25maWdGaWxlbmFtZSAoY29uc3QgRmNDaGFyOCAqdXJsKQp7CiAgICBGY0NoYXI4ICAgICpmaWxlLCAqZGlyLCAqKnBhdGgsICoqcDsKICAgIAogICAgaWYgKCF1cmwgfHwgISp1cmwpCiAgICB7Cgl1cmwgPSAoRmNDaGFyOCAqKSBnZXRlbnYgKCJGT05UQ09ORklHX0ZJTEUiKTsKCWlmICghdXJsKQoJICAgIHVybCA9IChGY0NoYXI4ICopIEZPTlRDT05GSUdfRklMRTsKICAgIH0KICAgIGZpbGUgPSAwOwoKI2lmZGVmIF9XSU4zMgogICAgaWYgKGlzYWxwaGEgKCp1cmwpICYmCgl1cmxbMV0gPT0gJzonICYmCgkodXJsWzJdID09ICcvJyB8fCB1cmxbMl0gPT0gJ1xcJykpCglnb3RvIGFic29sdXRlX3BhdGg7CiNlbmRpZgoKICAgIHN3aXRjaCAoKnVybCkgewogICAgY2FzZSAnfic6CglkaXIgPSBGY0NvbmZpZ0hvbWUgKCk7CglpZiAoZGlyKQoJICAgIGZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKGRpciwgdXJsICsgMSk7CgllbHNlCgkgICAgZmlsZSA9IDA7CglicmVhazsKI2lmZGVmIF9XSU4zMgogICAgY2FzZSAnXFwnOgogICAgYWJzb2x1dGVfcGF0aDoKI2VuZGlmCiAgICBjYXNlICcvJzoKCWZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKDAsIHVybCk7CglicmVhazsKICAgIGRlZmF1bHQ6CglwYXRoID0gRmNDb25maWdHZXRQYXRoICgpOwoJaWYgKCFwYXRoKQoJICAgIHJldHVybiAwOwoJZm9yIChwID0gcGF0aDsgKnA7IHArKykKCXsKCSAgICBmaWxlID0gRmNDb25maWdGaWxlRXhpc3RzICgqcCwgdXJsKTsKCSAgICBpZiAoZmlsZSkKCQlicmVhazsKCX0KCUZjQ29uZmlnRnJlZVBhdGggKHBhdGgpOwoJYnJlYWs7CiAgICB9CiAgICByZXR1cm4gZmlsZTsKfQoKLyoKICogTWFuYWdlIHRoZSBhcHBsaWNhdGlvbi1zcGVjaWZpYyBmb250cwogKi8KCkZjQm9vbApGY0NvbmZpZ0FwcEZvbnRBZGRGaWxlIChGY0NvbmZpZyAgICAqY29uZmlnLAoJCQljb25zdCBGY0NoYXI4ICAqZmlsZSkKewogICAgRmNGb250U2V0CSpzZXQ7CiAgICBGY1N0clNldAkqc3ViZGlyczsKICAgIEZjU3RyTGlzdAkqc3VibGlzdDsKICAgIEZjQ2hhcjgJKnN1YmRpcjsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIHN1YmRpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghc3ViZGlycykKCXJldHVybiBGY0ZhbHNlOwogICAgCiAgICBzZXQgPSBGY0NvbmZpZ0dldEZvbnRzIChjb25maWcsIEZjU2V0QXBwbGljYXRpb24pOwogICAgaWYgKCFzZXQpCiAgICB7CglzZXQgPSBGY0ZvbnRTZXRDcmVhdGUgKCk7CglpZiAoIXNldCkKCXsKCSAgICBGY1N0clNldERlc3Ryb3kgKHN1YmRpcnMpOwoJICAgIHJldHVybiBGY0ZhbHNlOwoJfQoJRmNDb25maWdTZXRGb250cyAoY29uZmlnLCBzZXQsIEZjU2V0QXBwbGljYXRpb24pOwogICAgfQoJCiAgICBpZiAoIUZjRmlsZVNjYW4gKHNldCwgc3ViZGlycywgMCwgY29uZmlnLT5ibGFua3MsIGZpbGUsIEZjRmFsc2UpKQogICAgewoJRmNTdHJTZXREZXN0cm95IChzdWJkaXJzKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgaWYgKChzdWJsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChzdWJkaXJzKSkpCiAgICB7Cgl3aGlsZSAoKHN1YmRpciA9IEZjU3RyTGlzdE5leHQgKHN1Ymxpc3QpKSkKCXsKCSAgICBGY0NvbmZpZ0FwcEZvbnRBZGREaXIgKGNvbmZpZywgc3ViZGlyKTsKCX0KCUZjU3RyTGlzdERvbmUgKHN1Ymxpc3QpOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjQ29uZmlnQXBwRm9udEFkZERpciAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgICAgIGNvbnN0IEZjQ2hhcjggICAqZGlyKQp7CiAgICBGY0ZvbnRTZXQJKnNldDsKICAgIEZjU3RyU2V0CSpzdWJkaXJzOwogICAgRmNTdHJMaXN0CSpzdWJsaXN0OwogICAgRmNDaGFyOAkqc3ViZGlyOwogICAgCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgc3ViZGlycyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFzdWJkaXJzKQoJcmV0dXJuIEZjRmFsc2U7CiAgICAKICAgIHNldCA9IEZjQ29uZmlnR2V0Rm9udHMgKGNvbmZpZywgRmNTZXRBcHBsaWNhdGlvbik7CiAgICBpZiAoIXNldCkKICAgIHsKCXNldCA9IEZjRm9udFNldENyZWF0ZSAoKTsKCWlmICghc2V0KQoJewoJICAgIEZjU3RyU2V0RGVzdHJveSAoc3ViZGlycyk7CgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl9CglGY0NvbmZpZ1NldEZvbnRzIChjb25maWcsIHNldCwgRmNTZXRBcHBsaWNhdGlvbik7CiAgICB9CiAgICAKICAgIGlmICghRmNEaXJTY2FuIChzZXQsIHN1YmRpcnMsIDAsIGNvbmZpZy0+YmxhbmtzLCBkaXIsIEZjRmFsc2UpKQogICAgewoJRmNTdHJTZXREZXN0cm95IChzdWJkaXJzKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgaWYgKChzdWJsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChzdWJkaXJzKSkpCiAgICB7Cgl3aGlsZSAoKHN1YmRpciA9IEZjU3RyTGlzdE5leHQgKHN1Ymxpc3QpKSkKCXsKCSAgICBGY0NvbmZpZ0FwcEZvbnRBZGREaXIgKGNvbmZpZywgc3ViZGlyKTsKCX0KCUZjU3RyTGlzdERvbmUgKHN1Ymxpc3QpOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKdm9pZApGY0NvbmZpZ0FwcEZvbnRDbGVhciAoRmNDb25maWcJICAgICpjb25maWcpCnsKICAgIEZjQ29uZmlnU2V0Rm9udHMgKGNvbmZpZywgMCwgRmNTZXRBcHBsaWNhdGlvbik7Cn0K