LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2NmZy5jLHYgMS4yMSAyMDAyLzA4LzIyIDA3OjM2OjQ0IGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKCkZjQ29uZmlnICAgICpfZmNDb25maWc7CgpGY0NvbmZpZyAqCkZjQ29uZmlnQ3JlYXRlICh2b2lkKQp7CiAgICBGY1NldE5hbWUJc2V0OwogICAgRmNDb25maWcJKmNvbmZpZzsKCiAgICBjb25maWcgPSBtYWxsb2MgKHNpemVvZiAoRmNDb25maWcpKTsKICAgIGlmICghY29uZmlnKQoJZ290byBiYWlsMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9DT05GSUcsIHNpemVvZiAoRmNDb25maWcpKTsKICAgIAogICAgY29uZmlnLT5jb25maWdEaXJzID0gRmNTdHJTZXRDcmVhdGUgKCk7CiAgICBpZiAoIWNvbmZpZy0+Y29uZmlnRGlycykKCWdvdG8gYmFpbDE7CiAgICAKICAgIGNvbmZpZy0+Y29uZmlnRmlsZXMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghY29uZmlnLT5jb25maWdGaWxlcykKCWdvdG8gYmFpbDI7CiAgICAKICAgIGNvbmZpZy0+Zm9udERpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghY29uZmlnLT5mb250RGlycykKCWdvdG8gYmFpbDM7CiAgICAKICAgIGNvbmZpZy0+Y2FjaGUgPSAwOwogICAgaWYgKCFGY0NvbmZpZ1NldENhY2hlIChjb25maWcsIChGY0NoYXI4ICopICgifi8iIEZDX1VTRVJfQ0FDSEVfRklMRSkpKQoJZ290byBiYWlsNDsKCiAgICBjb25maWctPmJsYW5rcyA9IDA7CgogICAgY29uZmlnLT5zdWJzdFBhdHRlcm4gPSAwOwogICAgY29uZmlnLT5zdWJzdEZvbnQgPSAwOwogICAgY29uZmlnLT5tYXhPYmplY3RzID0gMDsKICAgIGZvciAoc2V0ID0gRmNTZXRTeXN0ZW07IHNldCA8PSBGY1NldEFwcGxpY2F0aW9uOyBzZXQrKykKCWNvbmZpZy0+Zm9udHNbc2V0XSA9IDA7CgogICAgY29uZmlnLT5yZXNjYW5UaW1lID0gdGltZSgwKTsKICAgIGNvbmZpZy0+cmVzY2FuSW50ZXJ2YWwgPSAzMDsgICAgCiAgICAKICAgIHJldHVybiBjb25maWc7CgpiYWlsNDoKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5mb250RGlycyk7CmJhaWwzOgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmNvbmZpZ0ZpbGVzKTsKYmFpbDI6CiAgICBGY1N0clNldERlc3Ryb3kgKGNvbmZpZy0+Y29uZmlnRGlycyk7CmJhaWwxOgogICAgZnJlZSAoY29uZmlnKTsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0NPTkZJRywgc2l6ZW9mIChGY0NvbmZpZykpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNGaWxlVGltZSB7CiAgICB0aW1lX3QgIHRpbWU7CiAgICBGY0Jvb2wgIHNldDsKfSBGY0ZpbGVUaW1lOwoKc3RhdGljIEZjRmlsZVRpbWUKRmNDb25maWdOZXdlc3RGaWxlIChGY1N0clNldCAqZmlsZXMpCnsKICAgIEZjU3RyTGlzdAkgICAgKmxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGZpbGVzKTsKICAgIEZjRmlsZVRpbWUJICAgIG5ld2VzdCA9IHsgMCwgRmNGYWxzZSB9OwogICAgRmNDaGFyOAkgICAgKmZpbGU7CiAgICBzdHJ1Y3QgIHN0YXQgICAgc3RhdGI7CgogICAgaWYgKGxpc3QpCiAgICB7Cgl3aGlsZSAoKGZpbGUgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgkgICAgaWYgKHN0YXQgKChjaGFyICopIGZpbGUsICZzdGF0YikgPT0gMCkKCQlpZiAoIW5ld2VzdC5zZXQgfHwgc3RhdGIuc3RfbXRpbWUgLSBuZXdlc3QudGltZSA+IDApCgkJICAgIG5ld2VzdC50aW1lID0gc3RhdGIuc3RfbXRpbWU7CglGY1N0ckxpc3REb25lIChsaXN0KTsKICAgIH0KICAgIHJldHVybiBuZXdlc3Q7Cn0KCkZjQm9vbApGY0NvbmZpZ1VwdG9EYXRlIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY0ZpbGVUaW1lCWNvbmZpZ190aW1lLCBmb250X3RpbWU7CiAgICB0aW1lX3QJbm93ID0gdGltZSgwKTsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBjb25maWdfdGltZSA9IEZjQ29uZmlnTmV3ZXN0RmlsZSAoY29uZmlnLT5jb25maWdGaWxlcyk7CiAgICBmb250X3RpbWUgPSBGY0NvbmZpZ05ld2VzdEZpbGUgKGNvbmZpZy0+Y29uZmlnRGlycyk7CiAgICBpZiAoKGNvbmZpZ190aW1lLnNldCAmJiBjb25maWdfdGltZS50aW1lIC0gY29uZmlnLT5yZXNjYW5UaW1lID4gMCkgfHwKCShmb250X3RpbWUuc2V0ICYmIGZvbnRfdGltZS50aW1lIC0gY29uZmlnLT5yZXNjYW5UaW1lKSA+IDApCiAgICB7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGNvbmZpZy0+cmVzY2FuVGltZSA9IG5vdzsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyB2b2lkCkZjU3Vic3REZXN0cm95IChGY1N1YnN0ICpzKQp7CiAgICBGY1N1YnN0ICpuOwogICAgCiAgICB3aGlsZSAocykKICAgIHsKCW4gPSBzLT5uZXh0OwoJRmNUZXN0RGVzdHJveSAocy0+dGVzdCk7CglGY0VkaXREZXN0cm95IChzLT5lZGl0KTsKCXMgPSBuOwogICAgfQp9Cgp2b2lkCkZjQ29uZmlnRGVzdHJveSAoRmNDb25maWcgKmNvbmZpZykKewogICAgRmNTZXROYW1lCXNldDsKCiAgICBpZiAoY29uZmlnID09IF9mY0NvbmZpZykKCV9mY0NvbmZpZyA9IDA7CgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmNvbmZpZ0RpcnMpOwogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmZvbnREaXJzKTsKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5jb25maWdGaWxlcyk7CgogICAgRmNTdHJGcmVlIChjb25maWctPmNhY2hlKTsKCiAgICBGY1N1YnN0RGVzdHJveSAoY29uZmlnLT5zdWJzdFBhdHRlcm4pOwogICAgRmNTdWJzdERlc3Ryb3kgKGNvbmZpZy0+c3Vic3RGb250KTsKICAgIGZvciAoc2V0ID0gRmNTZXRTeXN0ZW07IHNldCA8PSBGY1NldEFwcGxpY2F0aW9uOyBzZXQrKykKCWlmIChjb25maWctPmZvbnRzW3NldF0pCgkgICAgRmNGb250U2V0RGVzdHJveSAoY29uZmlnLT5mb250c1tzZXRdKTsKICAgIGZyZWUgKGNvbmZpZyk7CiAgICBGY01lbUZyZWUgKEZDX01FTV9DT05GSUcsIHNpemVvZiAoRmNDb25maWcpKTsKfQoKLyoKICogU2NhbiB0aGUgY3VycmVudCBsaXN0IG9mIGRpcmVjdG9yaWVzIGluIHRoZSBjb25maWd1cmF0aW9uCiAqIGFuZCBidWlsZCB0aGUgc2V0IG9mIGF2YWlsYWJsZSBmb250cy4gVXBkYXRlIHRoZQogKiBwZXItdXNlciBjYWNoZSBmaWxlIHRvIHJlZmxlY3QgdGhlIG5ldyBjb25maWd1cmF0aW9uCiAqLwoKRmNCb29sCkZjQ29uZmlnQnVpbGRGb250cyAoRmNDb25maWcgKmNvbmZpZykKewogICAgRmNGb250U2V0CSAgICAqZm9udHM7CiAgICBGY0dsb2JhbENhY2hlICAgKmNhY2hlOwogICAgRmNTdHJMaXN0CSAgICAqbGlzdDsKICAgIEZjQ2hhcjgJICAgICpkaXI7CgogICAgZm9udHMgPSBGY0ZvbnRTZXRDcmVhdGUgKCk7CiAgICBpZiAoIWZvbnRzKQoJZ290byBiYWlsMDsKICAgIAogICAgY2FjaGUgPSBGY0dsb2JhbENhY2hlQ3JlYXRlICgpOwogICAgaWYgKCFjYWNoZSkKCWdvdG8gYmFpbDE7CgogICAgRmNHbG9iYWxDYWNoZUxvYWQgKGNhY2hlLCBjb25maWctPmNhY2hlKTsKCiAgICBsaXN0ID0gRmNDb25maWdHZXRGb250RGlycyAoY29uZmlnKTsKICAgIGlmICghbGlzdCkKCWdvdG8gYmFpbDE7CgogICAgd2hpbGUgKChkaXIgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19GT05UU0VUKQoJICAgIHByaW50ZiAoInNjYW4gZGlyICVzXG4iLCBkaXIpOwoJRmNEaXJTY2FuIChmb250cywgY29uZmlnLT5mb250RGlycywgY2FjaGUsIGNvbmZpZy0+YmxhbmtzLCBkaXIsIEZjRmFsc2UpOwogICAgfQogICAgCiAgICBGY1N0ckxpc3REb25lIChsaXN0KTsKICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRk9OVFNFVCkKCUZjRm9udFNldFByaW50IChmb250cyk7CgogICAgRmNHbG9iYWxDYWNoZVNhdmUgKGNhY2hlLCBjb25maWctPmNhY2hlKTsKICAgIEZjR2xvYmFsQ2FjaGVEZXN0cm95IChjYWNoZSk7CgogICAgRmNDb25maWdTZXRGb250cyAoY29uZmlnLCBmb250cywgRmNTZXRTeXN0ZW0pOwogICAgCiAgICByZXR1cm4gRmNUcnVlOwpiYWlsMToKICAgIEZjRm9udFNldERlc3Ryb3kgKGZvbnRzKTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNCb29sCkZjQ29uZmlnU2V0Q3VycmVudCAoRmNDb25maWcgKmNvbmZpZykKewogICAgaWYgKCFjb25maWctPmZvbnRzKQoJaWYgKCFGY0NvbmZpZ0J1aWxkRm9udHMgKGNvbmZpZykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CgogICAgaWYgKF9mY0NvbmZpZykKCUZjQ29uZmlnRGVzdHJveSAoX2ZjQ29uZmlnKTsKICAgIF9mY0NvbmZpZyA9IGNvbmZpZzsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQ29uZmlnICoKRmNDb25maWdHZXRDdXJyZW50ICh2b2lkKQp7CiAgICBpZiAoIV9mY0NvbmZpZykKCWlmICghRmNJbml0ICgpKQoJICAgIHJldHVybiAwOwogICAgcmV0dXJuIF9mY0NvbmZpZzsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQ29uZmlnRGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICBjb25zdCBGY0NoYXI4ICpkKQp7CiAgICByZXR1cm4gRmNTdHJTZXRBZGRGaWxlbmFtZSAoY29uZmlnLT5jb25maWdEaXJzLCBkKTsKfQoKRmNTdHJMaXN0ICoKRmNDb25maWdHZXRDb25maWdEaXJzIChGY0NvbmZpZyAgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gRmNTdHJMaXN0Q3JlYXRlIChjb25maWctPmNvbmZpZ0RpcnMpOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRGb250RGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgY29uc3QgRmNDaGFyOCAgICpkKQp7CiAgICByZXR1cm4gRmNTdHJTZXRBZGRGaWxlbmFtZSAoY29uZmlnLT5mb250RGlycywgZCk7Cn0KCkZjQm9vbApGY0NvbmZpZ0FkZERpciAoRmNDb25maWcJICAgICpjb25maWcsCgkJY29uc3QgRmNDaGFyOAkgICAgKmQpCnsKICAgIHJldHVybiAoRmNDb25maWdBZGRDb25maWdEaXIgKGNvbmZpZywgZCkgJiYgCgkgICAgRmNDb25maWdBZGRGb250RGlyIChjb25maWcsIGQpKTsKfQoKRmNTdHJMaXN0ICoKRmNDb25maWdHZXRGb250RGlycyAoRmNDb25maWcJKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBGY1N0ckxpc3RDcmVhdGUgKGNvbmZpZy0+Zm9udERpcnMpOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRDb25maWdGaWxlIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICAgY29uc3QgRmNDaGFyOCAgICpmKQp7CiAgICBGY0Jvb2wJcmV0OwogICAgRmNDaGFyOAkqZmlsZSA9IEZjQ29uZmlnRmlsZW5hbWUgKGYpOwogICAgCiAgICBpZiAoIWZpbGUpCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgcmV0ID0gRmNTdHJTZXRBZGQgKGNvbmZpZy0+Y29uZmlnRmlsZXMsIGZpbGUpOwogICAgRmNTdHJGcmVlIChmaWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCkZjU3RyTGlzdCAqCkZjQ29uZmlnR2V0Q29uZmlnRmlsZXMgKEZjQ29uZmlnICAgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gRmNTdHJMaXN0Q3JlYXRlIChjb25maWctPmNvbmZpZ0ZpbGVzKTsKfQoKRmNCb29sCkZjQ29uZmlnU2V0Q2FjaGUgKEZjQ29uZmlnCSpjb25maWcsCgkJICBjb25zdCBGY0NoYXI4CSpjKQp7CiAgICBGY0NoYXI4ICAgICpuZXcgPSBGY1N0ckNvcHlGaWxlbmFtZSAoYyk7CiAgICAKICAgIGlmICghbmV3KQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoY29uZmlnLT5jYWNoZSkKCUZjU3RyRnJlZSAoY29uZmlnLT5jYWNoZSk7CiAgICBjb25maWctPmNhY2hlID0gbmV3OwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNDaGFyOCAqCkZjQ29uZmlnR2V0Q2FjaGUgKEZjQ29uZmlnICAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+Y2FjaGU7Cn0KCkZjRm9udFNldCAqCkZjQ29uZmlnR2V0Rm9udHMgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY1NldE5hbWUJc2V0KQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+Zm9udHNbc2V0XTsKfQoKdm9pZApGY0NvbmZpZ1NldEZvbnRzIChGY0NvbmZpZwkqY29uZmlnLAoJCSAgRmNGb250U2V0CSpmb250cywKCQkgIEZjU2V0TmFtZQlzZXQpCnsKICAgIGlmIChjb25maWctPmZvbnRzW3NldF0pCglGY0ZvbnRTZXREZXN0cm95IChjb25maWctPmZvbnRzW3NldF0pOwogICAgY29uZmlnLT5mb250c1tzZXRdID0gZm9udHM7Cn0KCgoKRmNCbGFua3MgKgpGY0NvbmZpZ0dldEJsYW5rcyAoRmNDb25maWcJKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmJsYW5rczsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQmxhbmsgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY0NoYXIzMiAgICAJYmxhbmspCnsKICAgIEZjQmxhbmtzCSpiOwogICAgCiAgICBiID0gY29uZmlnLT5ibGFua3M7CiAgICBpZiAoIWIpCiAgICB7CgliID0gRmNCbGFua3NDcmVhdGUgKCk7CglpZiAoIWIpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoIUZjQmxhbmtzQWRkIChiLCBibGFuaykpCglyZXR1cm4gRmNGYWxzZTsKICAgIGNvbmZpZy0+YmxhbmtzID0gYjsKICAgIHJldHVybiBGY1RydWU7Cn0KCmludApGY0NvbmZpZ0dldFJlc2NhbkludmVydmFsIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+cmVzY2FuSW50ZXJ2YWw7Cn0KCkZjQm9vbApGY0NvbmZpZ1NldFJlc2NhbkludmVydmFsIChGY0NvbmZpZyAqY29uZmlnLCBpbnQgcmVzY2FuSW50ZXJ2YWwpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBjb25maWctPnJlc2NhbkludGVydmFsID0gcmVzY2FuSW50ZXJ2YWw7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRFZGl0IChGY0NvbmZpZwkqY29uZmlnLAoJCSBGY1Rlc3QJCSp0ZXN0LAoJCSBGY0VkaXQJCSplZGl0LAoJCSBGY01hdGNoS2luZAlraW5kKQp7CiAgICBGY1N1YnN0CSpzdWJzdCwgKipwcmV2OwogICAgRmNUZXN0CSp0OwogICAgaW50CQludW07CgogICAgc3Vic3QgPSAoRmNTdWJzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNTdWJzdCkpOwogICAgaWYgKCFzdWJzdCkKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGtpbmQgPT0gRmNNYXRjaFBhdHRlcm4pCglwcmV2ID0gJmNvbmZpZy0+c3Vic3RQYXR0ZXJuOwogICAgZWxzZQoJcHJldiA9ICZjb25maWctPnN1YnN0Rm9udDsKICAgIGZvciAoOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KTsKICAgICpwcmV2ID0gc3Vic3Q7CiAgICBzdWJzdC0+bmV4dCA9IDA7CiAgICBzdWJzdC0+dGVzdCA9IHRlc3Q7CiAgICBzdWJzdC0+ZWRpdCA9IGVkaXQ7CiAgICBudW0gPSAwOwogICAgZm9yICh0ID0gdGVzdDsgdDsgdCA9IHQtPm5leHQpCiAgICB7CglpZiAodC0+a2luZCA9PSBGY01hdGNoRGVmYXVsdCkKCSAgICB0LT5raW5kID0ga2luZDsKCW51bSsrOwogICAgfQogICAgaWYgKGNvbmZpZy0+bWF4T2JqZWN0cyA8IG51bSkKCWNvbmZpZy0+bWF4T2JqZWN0cyA9IG51bTsKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCJBZGQgU3Vic3QgIik7CglGY1N1YnN0UHJpbnQgKHN1YnN0KTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnR5cGVkZWYgc3RydWN0IF9GY1N1YlN0YXRlIHsKICAgIEZjUGF0dGVybkVsdCAgICplbHQ7CiAgICBGY1ZhbHVlTGlzdCAgICAqdmFsdWU7Cn0gRmNTdWJTdGF0ZTsKCnN0YXRpYyBGY1ZhbHVlCkZjQ29uZmlnUHJvbW90ZSAoRmNWYWx1ZSB2LCBGY1ZhbHVlIHUpCnsKICAgIGlmICh2LnR5cGUgPT0gRmNUeXBlSW50ZWdlcikKICAgIHsKCXYudHlwZSA9IEZjVHlwZURvdWJsZTsKCXYudS5kID0gKGRvdWJsZSkgdi51Lmk7CiAgICB9CiAgICBlbHNlIGlmICh2LnR5cGUgPT0gRmNUeXBlVm9pZCAmJiB1LnR5cGUgPT0gRmNUeXBlTWF0cml4KQogICAgewoJdi51Lm0gPSAmRmNJZGVudGl0eU1hdHJpeDsKCXYudHlwZSA9IEZjVHlwZU1hdHJpeDsKICAgIH0KICAgIGVsc2UgaWYgKHYudHlwZSA9PSBGY1R5cGVTdHJpbmcgJiYgdS50eXBlID09IEZjVHlwZUxhbmdTZXQpCiAgICB7Cgl2LnUubCA9IEZjTGFuZ1NldFByb21vdGUgKHYudS5zKTsKCXYudHlwZSA9IEZjVHlwZUxhbmdTZXQ7CiAgICB9CiAgICByZXR1cm4gdjsKfQoKRmNCb29sCkZjQ29uZmlnQ29tcGFyZVZhbHVlIChGY1ZhbHVlCW0sCgkJICAgICAgRmNPcAlvcCwKCQkgICAgICBGY1ZhbHVlCXYpCnsKICAgIEZjQm9vbCAgICByZXQgPSBGY0ZhbHNlOwogICAgCiAgICBtID0gRmNDb25maWdQcm9tb3RlIChtLCB2KTsKICAgIHYgPSBGY0NvbmZpZ1Byb21vdGUgKHYsIG0pOwogICAgaWYgKG0udHlwZSA9PSB2LnR5cGUpIAogICAgewoJc3dpdGNoIChtLnR5cGUpIHsKCWNhc2UgRmNUeXBlSW50ZWdlcjoKCSAgICBicmVhazsJLyogRmNDb25maWdQcm9tb3RlIHByZXZlbnRzIHRoaXMgZnJvbSBoYXBwZW5pbmcgKi8KCWNhc2UgRmNUeXBlRG91YmxlOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBtLnUuZCA9PSB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCSAgICBjYXNlIEZjT3BOb3RDb250YWluczoKCQlyZXQgPSBtLnUuZCAhPSB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BMZXNzOiAgICAKCQlyZXQgPSBtLnUuZCA8IHYudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcExlc3NFcXVhbDogICAgCgkJcmV0ID0gbS51LmQgPD0gdi51LmQ7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTW9yZTogICAgCgkJcmV0ID0gbS51LmQgPiB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BNb3JlRXF1YWw6ICAgIAoJCXJldCA9IG0udS5kID49IHYudS5kOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVCb29sOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDogICAgCgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gbS51LmIgPT0gdi51LmI7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gbS51LmIgIT0gdi51LmI7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZVN0cmluZzoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6ICAgIAoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCXJldCA9IEZjU3RyQ21wSWdub3JlQ2FzZSAobS51LnMsIHYudS5zKSA9PSAwOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgoJCXJldCA9IEZjU3RyQ21wSWdub3JlQ2FzZSAobS51LnMsIHYudS5zKSAhPSAwOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVNYXRyaXg6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOgoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCXJldCA9IEZjTWF0cml4RXF1YWwgKG0udS5tLCB2LnUubSk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkgICAgY2FzZSBGY09wTm90Q29udGFpbnM6CgkJcmV0ID0gIUZjTWF0cml4RXF1YWwgKG0udS5tLCB2LnUubSk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZUNoYXJTZXQ6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCS8qIG0gY29udGFpbnMgdiBpZiB2IGlzIGEgc3Vic2V0IG9mIG0gKi8KCQlyZXQgPSBGY0NoYXJTZXRJc1N1YnNldCAodi51LmMsIG0udS5jKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RDb250YWluczoKCQkvKiBtIGNvbnRhaW5zIHYgaWYgdiBpcyBhIHN1YnNldCBvZiBtICovCgkJcmV0ID0gIUZjQ2hhclNldElzU3Vic2V0ICh2LnUuYywgbS51LmMpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcEVxdWFsOgoJCXJldCA9IEZjQ2hhclNldEVxdWFsIChtLnUuYywgdi51LmMpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJCXJldCA9ICFGY0NoYXJTZXRFcXVhbCAobS51LmMsIHYudS5jKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlTGFuZ1NldDoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gRmNMYW5nU2V0Q29tcGFyZSAodi51LmwsIG0udS5sKSAhPSBGY0xhbmdEaWZmZXJlbnRMYW5nOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgoJCXJldCA9IEZjTGFuZ1NldENvbXBhcmUgKHYudS5sLCBtLnUubCkgPT0gRmNMYW5nRGlmZmVyZW50TGFuZzsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCQlyZXQgPSBGY0xhbmdTZXRFcXVhbCAodi51LmwsIG0udS5sKTsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCQlyZXQgPSAhRmNMYW5nU2V0RXF1YWwgKHYudS5sLCBtLnUubCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZVZvaWQ6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOgoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCXJldCA9IEZjVHJ1ZTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlRlRGYWNlOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBtLnUuZiA9PSB2LnUuZjsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDoKCSAgICBjYXNlIEZjT3BOb3RDb250YWluczoKCQlyZXQgPSBtLnUuZiAhPSB2LnUuZjsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCX0KICAgIH0KICAgIGVsc2UKICAgIHsKCWlmIChvcCA9PSBGY09wTm90RXF1YWwgfHwgb3AgPT0gRmNPcE5vdENvbnRhaW5zKQoJICAgIHJldCA9IEZjVHJ1ZTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCgpzdGF0aWMgRmNWYWx1ZQpGY0NvbmZpZ0V2YWx1YXRlIChGY1BhdHRlcm4gKnAsIEZjRXhwciAqZSkKewogICAgRmNWYWx1ZQl2LCB2bCwgdnI7CiAgICBGY1Jlc3VsdAlyOwogICAgRmNNYXRyaXgJKm07CiAgICAKICAgIHN3aXRjaCAoZS0+b3ApIHsKICAgIGNhc2UgRmNPcEludGVnZXI6Cgl2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJdi51LmkgPSBlLT51Lml2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcERvdWJsZToKCXYudHlwZSA9IEZjVHlwZURvdWJsZTsKCXYudS5kID0gZS0+dS5kdmFsOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BTdHJpbmc6Cgl2LnR5cGUgPSBGY1R5cGVTdHJpbmc7Cgl2LnUucyA9IGUtPnUuc3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcE1hdHJpeDoKCXYudHlwZSA9IEZjVHlwZU1hdHJpeDsKCXYudS5tID0gZS0+dS5tdmFsOwoJdiA9IEZjVmFsdWVTYXZlICh2KTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ2hhclNldDoKCXYudHlwZSA9IEZjVHlwZUNoYXJTZXQ7Cgl2LnUuYyA9IGUtPnUuY3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcEJvb2w6Cgl2LnR5cGUgPSBGY1R5cGVCb29sOwoJdi51LmIgPSBlLT51LmJ2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcEZpZWxkOgoJciA9IEZjUGF0dGVybkdldCAocCwgZS0+dS5maWVsZCwgMCwgJnYpOwoJaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDb25zdDoKCWlmIChGY05hbWVDb25zdGFudCAoZS0+dS5jb25zdGFudCwgJnYudS5pKSkKCSAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNPcFF1ZXN0OgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7CglpZiAodmwudHlwZSA9PSBGY1R5cGVCb29sKQoJewoJICAgIGlmICh2bC51LmIpCgkJdiA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5yaWdodC0+dS50cmVlLmxlZnQpOwoJICAgIGVsc2UKCQl2ID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0LT51LnRyZWUucmlnaHQpOwoJfQoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BFcXVhbDoKICAgIGNhc2UgRmNPcE5vdEVxdWFsOgogICAgY2FzZSBGY09wTGVzczoKICAgIGNhc2UgRmNPcExlc3NFcXVhbDoKICAgIGNhc2UgRmNPcE1vcmU6CiAgICBjYXNlIEZjT3BNb3JlRXF1YWw6CiAgICBjYXNlIEZjT3BDb250YWluczoKICAgIGNhc2UgRmNPcE5vdENvbnRhaW5zOgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7Cgl2ciA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5yaWdodCk7Cgl2LnR5cGUgPSBGY1R5cGVCb29sOwoJdi51LmIgPSBGY0NvbmZpZ0NvbXBhcmVWYWx1ZSAodmwsIGUtPm9wLCB2cik7CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJRmNWYWx1ZURlc3Ryb3kgKHZyKTsKCWJyZWFrOwkKICAgIGNhc2UgRmNPcE9yOgogICAgY2FzZSBGY09wQW5kOgogICAgY2FzZSBGY09wUGx1czoKICAgIGNhc2UgRmNPcE1pbnVzOgogICAgY2FzZSBGY09wVGltZXM6CiAgICBjYXNlIEZjT3BEaXZpZGU6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCXZyID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0KTsKCXZsID0gRmNDb25maWdQcm9tb3RlICh2bCwgdnIpOwoJdnIgPSBGY0NvbmZpZ1Byb21vdGUgKHZyLCB2bCk7CglpZiAodmwudHlwZSA9PSB2ci50eXBlKQoJewoJICAgIHN3aXRjaCAodmwudHlwZSkgewoJICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BQbHVzOgkgICAKCQkgICAgdi50eXBlID0gRmNUeXBlRG91YmxlOwoJCSAgICB2LnUuZCA9IHZsLnUuZCArIHZyLnUuZDsgCgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcE1pbnVzOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CgkJICAgIHYudS5kID0gdmwudS5kIC0gdnIudS5kOyAKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wVGltZXM6CgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgKiB2ci51LmQ7IAoJCSAgICBicmVhazsKCQljYXNlIEZjT3BEaXZpZGU6CgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgLyB2ci51LmQ7IAoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOyAKCQkgICAgYnJlYWs7CgkJfQoJCWlmICh2LnR5cGUgPT0gRmNUeXBlRG91YmxlICYmCgkJICAgIHYudS5kID09IChkb3VibGUpIChpbnQpIHYudS5kKQoJCXsKCQkgICAgdi50eXBlID0gRmNUeXBlSW50ZWdlcjsKCQkgICAgdi51LmkgPSAoaW50KSB2LnUuZDsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY1R5cGVCb29sOgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BPcjoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSB2bC51LmIgfHwgdnIudS5iOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BBbmQ6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gdmwudS5iICYmIHZyLnUuYjsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsgCgkJICAgIGJyZWFrOwoJCX0KCQlicmVhazsKCSAgICBjYXNlIEZjVHlwZVN0cmluZzoKCQlzd2l0Y2ggKGUtPm9wKSB7CgkJY2FzZSBGY09wUGx1czoKCQkgICAgdi50eXBlID0gRmNUeXBlU3RyaW5nOwoJCSAgICB2LnUucyA9IEZjU3RyUGx1cyAodmwudS5zLCB2ci51LnMpOwoJCSAgICBpZiAoIXYudS5zKQoJCQl2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY1R5cGVNYXRyaXg6CgkJc3dpdGNoIChlLT5vcCkgewoJCWNhc2UgRmNPcFRpbWVzOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVNYXRyaXg7CgkJICAgIG0gPSBtYWxsb2MgKHNpemVvZiAoRmNNYXRyaXgpKTsKCQkgICAgaWYgKG0pCgkJICAgIHsKCQkJRmNNZW1BbGxvYyAoRkNfTUVNX01BVFJJWCwgc2l6ZW9mIChGY01hdHJpeCkpOwoJCQlGY01hdHJpeE11bHRpcGx5IChtLCB2bC51Lm0sIHZyLnUubSk7CgkJCXYudS5tID0gbTsKCQkgICAgfQoJCSAgICBlbHNlCgkJICAgIHsKCQkJdi50eXBlID0gRmNUeXBlVm9pZDsKCQkgICAgfQoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQl2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCWJyZWFrOwoJICAgIH0KCX0KCWVsc2UKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJRmNWYWx1ZURlc3Ryb3kgKHZsKTsKCUZjVmFsdWVEZXN0cm95ICh2cik7CglicmVhazsKICAgIGNhc2UgRmNPcE5vdDoKCXZsID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLmxlZnQpOwoJc3dpdGNoICh2bC50eXBlKSB7CgljYXNlIEZjVHlwZUJvb2w6CgkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCSAgICB2LnUuYiA9ICF2bC51LmI7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CgkgICAgYnJlYWs7Cgl9CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJdi50eXBlID0gRmNUeXBlVm9pZDsKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIHY7Cn0KCnN0YXRpYyBGY1ZhbHVlTGlzdCAqCkZjQ29uZmlnTWF0Y2hWYWx1ZUxpc3QgKEZjUGF0dGVybgkqcCwKCQkJRmNUZXN0CQkqdCwKCQkJRmNWYWx1ZUxpc3QJKnZhbHVlcykKewogICAgRmNWYWx1ZUxpc3QJICAgICpyZXQgPSAwOwogICAgRmNFeHByCSAgICAqZSA9IHQtPmV4cHI7CiAgICBGY1ZhbHVlCSAgICB2YWx1ZTsKICAgIEZjVmFsdWVMaXN0CSAgICAqdjsKICAgIAogICAgd2hpbGUgKGUpCiAgICB7CglpZiAoZS0+b3AgPT0gRmNPcENvbW1hKQoJewoJICAgIHZhbHVlID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLmxlZnQpOwoJICAgIGUgPSBlLT51LnRyZWUucmlnaHQ7Cgl9CgllbHNlCgl7CgkgICAgdmFsdWUgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlKTsKCSAgICBlID0gMDsKCX0KCglmb3IgKHYgPSB2YWx1ZXM7IHY7IHYgPSB2LT5uZXh0KQoJewoJICAgIGlmIChGY0NvbmZpZ0NvbXBhcmVWYWx1ZSAodi0+dmFsdWUsIHQtPm9wLCB2YWx1ZSkpCgkgICAgewoJCWlmICghcmV0KQoJCSAgICByZXQgPSB2OwoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCWlmICh0LT5xdWFsID09IEZjUXVhbEFsbCkKCQl7CgkJICAgIHJldCA9IDA7CgkJICAgIGJyZWFrOwoJCX0KCSAgICB9Cgl9CglGY1ZhbHVlRGVzdHJveSAodmFsdWUpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEZjVmFsdWVMaXN0ICoKRmNDb25maWdWYWx1ZXMgKEZjUGF0dGVybiAqcCwgRmNFeHByICplLCBGY1ZhbHVlQmluZGluZyBiaW5kaW5nKQp7CiAgICBGY1ZhbHVlTGlzdAkqbDsKICAgIAogICAgaWYgKCFlKQoJcmV0dXJuIDA7CiAgICBsID0gKEZjVmFsdWVMaXN0ICopIG1hbGxvYyAoc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwogICAgaWYgKCFsKQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fVkFMTElTVCwgc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwogICAgaWYgKGUtPm9wID09IEZjT3BDb21tYSkKICAgIHsKCWwtPnZhbHVlID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLmxlZnQpOwoJbC0+bmV4dCAgPSBGY0NvbmZpZ1ZhbHVlcyAocCwgZS0+dS50cmVlLnJpZ2h0LCBiaW5kaW5nKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWwtPnZhbHVlID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZSk7CglsLT5uZXh0ICA9IDA7CiAgICB9CiAgICBsLT5iaW5kaW5nID0gYmluZGluZzsKICAgIHdoaWxlIChsICYmIGwtPnZhbHVlLnR5cGUgPT0gRmNUeXBlVm9pZCkKICAgIHsKCUZjVmFsdWVMaXN0CSpuZXh0ID0gbC0+bmV4dDsKCQoJRmNNZW1GcmVlIChGQ19NRU1fVkFMTElTVCwgc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwoJZnJlZSAobCk7CglsID0gbmV4dDsKICAgIH0KICAgIHJldHVybiBsOwp9CgpzdGF0aWMgRmNCb29sCkZjQ29uZmlnQWRkIChGY1ZhbHVlTGlzdCAgICAqKmhlYWQsCgkgICAgIEZjVmFsdWVMaXN0ICAgICpwb3NpdGlvbiwKCSAgICAgRmNCb29sCSAgICBhcHBlbmQsCgkgICAgIEZjVmFsdWVMaXN0ICAgICpuZXcpCnsKICAgIEZjVmFsdWVMaXN0ICAgICoqcHJldiwgKmxhc3Q7CiAgICAKICAgIGlmIChhcHBlbmQpCiAgICB7CglpZiAocG9zaXRpb24pCgkgICAgcHJldiA9ICZwb3NpdGlvbi0+bmV4dDsKCWVsc2UKCSAgICBmb3IgKHByZXYgPSBoZWFkOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KQoJCTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWlmIChwb3NpdGlvbikKCXsKCSAgICBmb3IgKHByZXYgPSBoZWFkOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KQoJICAgIHsKCQlpZiAoKnByZXYgPT0gcG9zaXRpb24pCgkJICAgIGJyZWFrOwoJICAgIH0KCX0KCWVsc2UKCSAgICBwcmV2ID0gaGVhZDsKCglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJewoJICAgIGlmICghKnByZXYpCgkJcHJpbnRmICgicG9zaXRpb24gbm90IG9uIGxpc3RcbiIpOwoJfQogICAgfQoKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCIlcyBsaXN0IGJlZm9yZSAiLCBhcHBlbmQgPyAiQXBwZW5kIiA6ICJQcmVwZW5kIik7CglGY1ZhbHVlTGlzdFByaW50ICgqaGVhZCk7CglwcmludGYgKCJcbiIpOwogICAgfQogICAgCiAgICBpZiAobmV3KQogICAgewoJbGFzdCA9IG5ldzsKCXdoaWxlIChsYXN0LT5uZXh0KQoJICAgIGxhc3QgPSBsYXN0LT5uZXh0OwogICAgCglsYXN0LT5uZXh0ID0gKnByZXY7CgkqcHJldiA9IG5ldzsKICAgIH0KICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIiVzIGxpc3QgYWZ0ZXIgIiwgYXBwZW5kID8gIkFwcGVuZCIgOiAiUHJlcGVuZCIpOwoJRmNWYWx1ZUxpc3RQcmludCAoKmhlYWQpOwoJcHJpbnRmICgiXG4iKTsKICAgIH0KICAgIAogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIHZvaWQKRmNDb25maWdEZWwgKEZjVmFsdWVMaXN0ICAgICoqaGVhZCwKCSAgICAgRmNWYWx1ZUxpc3QgICAgKnBvc2l0aW9uKQp7CiAgICBGY1ZhbHVlTGlzdCAgICAqKnByZXY7CgogICAgZm9yIChwcmV2ID0gaGVhZDsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKICAgIHsKCWlmICgqcHJldiA9PSBwb3NpdGlvbikKCXsKCSAgICAqcHJldiA9IHBvc2l0aW9uLT5uZXh0OwoJICAgIHBvc2l0aW9uLT5uZXh0ID0gMDsKCSAgICBGY1ZhbHVlTGlzdERlc3Ryb3kgKHBvc2l0aW9uKTsKCSAgICBicmVhazsKCX0KICAgIH0KfQoKc3RhdGljIHZvaWQKRmNDb25maWdQYXR0ZXJuQWRkIChGY1BhdHRlcm4JKnAsCgkJICAgIGNvbnN0IGNoYXIJKm9iamVjdCwKCQkgICAgRmNWYWx1ZUxpc3QJKmxpc3QsCgkJICAgIEZjQm9vbAlhcHBlbmQpCnsKICAgIGlmIChsaXN0KQogICAgewoJRmNQYXR0ZXJuRWx0ICAgICplID0gRmNQYXR0ZXJuSW5zZXJ0RWx0IChwLCBvYmplY3QpOwogICAgCglpZiAoIWUpCgkgICAgcmV0dXJuOwoJRmNDb25maWdBZGQgKCZlLT52YWx1ZXMsIDAsIGFwcGVuZCwgbGlzdCk7CiAgICB9Cn0KCi8qCiAqIERlbGV0ZSBhbGwgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBhIGZpZWxkCiAqLwpzdGF0aWMgdm9pZApGY0NvbmZpZ1BhdHRlcm5EZWwgKEZjUGF0dGVybgkqcCwKCQkgICAgY29uc3QgY2hhcgkqb2JqZWN0KQp7CiAgICBGY1BhdHRlcm5FbHQgICAgKmUgPSBGY1BhdHRlcm5GaW5kRWx0IChwLCBvYmplY3QpOwogICAgaWYgKCFlKQoJcmV0dXJuOwogICAgd2hpbGUgKGUtPnZhbHVlcykKCUZjQ29uZmlnRGVsICgmZS0+dmFsdWVzLCBlLT52YWx1ZXMpOwp9CgpzdGF0aWMgdm9pZApGY0NvbmZpZ1BhdHRlcm5DYW5vbiAoRmNQYXR0ZXJuCSAgICAqcCwKCQkgICAgICBjb25zdCBjaGFyICAgICpvYmplY3QpCnsKICAgIEZjUGF0dGVybkVsdCAgICAqZSA9IEZjUGF0dGVybkZpbmRFbHQgKHAsIG9iamVjdCk7CiAgICBpZiAoIWUpCglyZXR1cm47CiAgICBpZiAoIWUtPnZhbHVlcykKCUZjUGF0dGVybkRlbCAocCwgb2JqZWN0KTsKfQoKRmNCb29sCkZjQ29uZmlnU3Vic3RpdHV0ZVdpdGhQYXQgKEZjQ29uZmlnICAgICpjb25maWcsCgkJCSAgIEZjUGF0dGVybiAgICpwLAoJCQkgICBGY1BhdHRlcm4gICAqcF9wYXQsCgkJCSAgIEZjTWF0Y2hLaW5kIGtpbmQpCnsKICAgIEZjU3Vic3QJICAgICpzOwogICAgRmNTdWJTdGF0ZQkgICAgKnN0OwogICAgaW50CQkgICAgaTsKICAgIEZjVGVzdAkgICAgKnQ7CiAgICBGY0VkaXQJICAgICplOwogICAgRmNWYWx1ZUxpc3QJICAgICpsOwogICAgRmNQYXR0ZXJuCSAgICAqbTsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIHN0ID0gKEZjU3ViU3RhdGUgKikgbWFsbG9jIChjb25maWctPm1heE9iamVjdHMgKiBzaXplb2YgKEZjU3ViU3RhdGUpKTsKICAgIGlmICghc3QgJiYgY29uZmlnLT5tYXhPYmplY3RzKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fU1VCU1RBVEUsIGNvbmZpZy0+bWF4T2JqZWN0cyAqIHNpemVvZiAoRmNTdWJTdGF0ZSkpOwoKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCJGY0NvbmZpZ1N1YnN0aXR1dGUgIik7CglGY1BhdHRlcm5QcmludCAocCk7CiAgICB9CiAgICBpZiAoa2luZCA9PSBGY01hdGNoUGF0dGVybikKCXMgPSBjb25maWctPnN1YnN0UGF0dGVybjsKICAgIGVsc2UKCXMgPSBjb25maWctPnN1YnN0Rm9udDsKICAgIGZvciAoOyBzOyBzID0gcy0+bmV4dCkKICAgIHsKCS8qCgkgKiBDaGVjayB0aGUgdGVzdHMgdG8gc2VlIGlmCgkgKiB0aGV5IGFsbCBtYXRjaCB0aGUgcGF0dGVybgoJICovCglmb3IgKHQgPSBzLT50ZXN0LCBpID0gMDsgdDsgdCA9IHQtPm5leHQsIGkrKykKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJICAgIHsKCQlwcmludGYgKCJGY0NvbmZpZ1N1YnN0aXR1dGUgdGVzdCAiKTsKCQlGY1Rlc3RQcmludCAodCk7CgkgICAgfQoJICAgIHN0W2ldLmVsdCA9IDA7CgkgICAgaWYgKGtpbmQgPT0gRmNNYXRjaEZvbnQgJiYgdC0+a2luZCA9PSBGY01hdGNoUGF0dGVybikKCQltID0gcF9wYXQ7CgkgICAgZWxzZQoJCW0gPSBwOwoJICAgIGlmIChtKQoJCXN0W2ldLmVsdCA9IEZjUGF0dGVybkZpbmRFbHQgKG0sIHQtPmZpZWxkKTsKCSAgICBlbHNlCgkJc3RbaV0uZWx0ID0gMDsKCSAgICAvKgoJICAgICAqIElmIHRoZXJlJ3Mgbm8gc3VjaCBmaWVsZCBpbiB0aGUgZm9udCwKCSAgICAgKiB0aGVuIEZjUXVhbEFsbCBtYXRjaGVzIHdoaWxlIEZjUXVhbEFueSBkb2VzIG5vdAoJICAgICAqLwoJICAgIGlmICghc3RbaV0uZWx0KQoJICAgIHsKCQlpZiAodC0+cXVhbCA9PSBGY1F1YWxBbGwpCgkJewoJCSAgICBzdFtpXS52YWx1ZSA9IDA7CgkJICAgIGNvbnRpbnVlOwoJCX0KCQllbHNlCgkJICAgIGJyZWFrOwoJICAgIH0KCSAgICAvKgoJICAgICAqIENoZWNrIHRvIHNlZSBpZiB0aGVyZSBpcyBhIG1hdGNoLCBtYXJrIHRoZSBsb2NhdGlvbgoJICAgICAqIHRvIGFwcGx5IG1hdGNoLXJlbGF0aXZlIGVkaXRzCgkgICAgICovCgkgICAgc3RbaV0udmFsdWUgPSBGY0NvbmZpZ01hdGNoVmFsdWVMaXN0IChtLCB0LCBzdFtpXS5lbHQtPnZhbHVlcyk7CgkgICAgaWYgKCFzdFtpXS52YWx1ZSkKCQlicmVhazsKCSAgICBpZiAodC0+cXVhbCA9PSBGY1F1YWxGaXJzdCAmJiBzdFtpXS52YWx1ZSAhPSBzdFtpXS5lbHQtPnZhbHVlcykKCQlicmVhazsKCSAgICBpZiAodC0+cXVhbCA9PSBGY1F1YWxOb3RGaXJzdCAmJiBzdFtpXS52YWx1ZSA9PSBzdFtpXS5lbHQtPnZhbHVlcykKCQlicmVhazsKCX0KCWlmICh0KQoJewoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgkJcHJpbnRmICgiTm8gbWF0Y2hcbiIpOwoJICAgIGNvbnRpbnVlOwoJfQoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCXsKCSAgICBwcmludGYgKCJTdWJzdGl0dXRlICIpOwoJICAgIEZjU3Vic3RQcmludCAocyk7Cgl9Cglmb3IgKGUgPSBzLT5lZGl0OyBlOyBlID0gZS0+bmV4dCkKCXsKCSAgICAvKgoJICAgICAqIEV2YWx1YXRlIHRoZSBsaXN0IG9mIGV4cHJlc3Npb25zCgkgICAgICovCgkgICAgbCA9IEZjQ29uZmlnVmFsdWVzIChwLCBlLT5leHByLCBlLT5iaW5kaW5nKTsKCSAgICAvKgoJICAgICAqIExvY2F0ZSBhbnkgdGVzdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBmaWVsZCwgc2tpcHBpbmcKCSAgICAgKiB0ZXN0cyBhc3NvY2lhdGVkIHdpdGggdGhlIHBhdHRlcm4gd2hlbiBzdWJzdGl0dXRpbmcgaW4KCSAgICAgKiB0aGUgZm9udAoJICAgICAqLwoJICAgIGZvciAodCA9IHMtPnRlc3QsIGkgPSAwOyB0OyB0ID0gdC0+bmV4dCwgaSsrKQoJICAgIHsKCQlpZiAoKHQtPmtpbmQgPT0gRmNNYXRjaEZvbnQgfHwga2luZCA9PSBGY01hdGNoUGF0dGVybikgJiYKCQkgICAgIUZjU3RyQ21wSWdub3JlQ2FzZSAoKEZjQ2hhcjggKikgdC0+ZmllbGQsIAoJCQkJCSAoRmNDaGFyOCAqKSBlLT5maWVsZCkpCgkJICAgIGJyZWFrOwoJICAgIH0KCSAgICBzd2l0Y2ggKGUtPm9wKSB7CgkgICAgY2FzZSBGY09wQXNzaWduOgoJCS8qCgkJICogSWYgdGhlcmUgd2FzIGEgdGVzdCwgdGhlbiByZXBsYWNlIHRoZSBtYXRjaGVkCgkJICogdmFsdWUgd2l0aCB0aGUgbmV3IGxpc3Qgb2YgdmFsdWVzCgkJICovCgkJaWYgKHQpCgkJewoJCSAgICBGY1ZhbHVlTGlzdAkqdGhpc1ZhbHVlID0gc3RbaV0udmFsdWU7CgkJICAgIEZjVmFsdWVMaXN0CSpuZXh0VmFsdWUgPSB0aGlzVmFsdWUgPyB0aGlzVmFsdWUtPm5leHQgOiAwOwoJCSAgICAKCQkgICAgLyoKCQkgICAgICogQXBwZW5kIHRoZSBuZXcgbGlzdCBvZiB2YWx1ZXMgYWZ0ZXIgdGhlIGN1cnJlbnQgdmFsdWUKCQkgICAgICovCgkJICAgIEZjQ29uZmlnQWRkICgmc3RbaV0uZWx0LT52YWx1ZXMsIHRoaXNWYWx1ZSwgRmNUcnVlLCBsKTsKCQkgICAgLyoKCQkgICAgICogRGVsZXRlIHRoZSBtYXJrZWQgdmFsdWUKCQkgICAgICovCgkJICAgIEZjQ29uZmlnRGVsICgmc3RbaV0uZWx0LT52YWx1ZXMsIHRoaXNWYWx1ZSk7CgkJICAgIC8qCgkJICAgICAqIEFkanVzdCBhbnkgcG9pbnRlcnMgaW50byB0aGUgdmFsdWUgbGlzdCB0byBlbnN1cmUKCQkgICAgICogZnV0dXJlIGVkaXRzIG9jY3VyIGF0IHRoZSBzYW1lIHBsYWNlCgkJICAgICAqLwoJCSAgICBmb3IgKHQgPSBzLT50ZXN0LCBpID0gMDsgdDsgdCA9IHQtPm5leHQsIGkrKykKCQkgICAgewoJCQlpZiAoc3RbaV0udmFsdWUgPT0gdGhpc1ZhbHVlKQoJCQkgICAgc3RbaV0udmFsdWUgPSBuZXh0VmFsdWU7CgkJICAgIH0KCQkgICAgYnJlYWs7CgkJfQoJCS8qIGZhbGwgdGhyb3VnaCAuLi4gKi8KCSAgICBjYXNlIEZjT3BBc3NpZ25SZXBsYWNlOgoJCS8qCgkJICogRGVsZXRlIGFsbCBvZiB0aGUgdmFsdWVzIGFuZCBpbnNlcnQKCQkgKiB0aGUgbmV3IHNldAoJCSAqLwoJCUZjQ29uZmlnUGF0dGVybkRlbCAocCwgZS0+ZmllbGQpOwoJCUZjQ29uZmlnUGF0dGVybkFkZCAocCwgZS0+ZmllbGQsIGwsIEZjVHJ1ZSk7CgkJLyoKCQkgKiBBZGp1c3QgYW55IHBvaW50ZXJzIGludG8gdGhlIHZhbHVlIGxpc3QgYXMgdGhleSBubwoJCSAqIGxvbmdlciBwb2ludCB0byBhbnl0aGluZyB2YWxpZAoJCSAqLwoJCWlmICh0KQoJCXsKCQkgICAgRmNQYXR0ZXJuRWx0ICAgICp0aGlzRWx0ID0gc3RbaV0uZWx0OwoJCSAgICBmb3IgKHQgPSBzLT50ZXN0LCBpID0gMDsgdDsgdCA9IHQtPm5leHQsIGkrKykKCQkgICAgewoJCQlpZiAoc3RbaV0uZWx0ID09IHRoaXNFbHQpCgkJCSAgICBzdFtpXS52YWx1ZSA9IDA7CgkJICAgIH0KCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wUHJlcGVuZDoKCQlpZiAodCkKCQl7CgkJICAgIEZjQ29uZmlnQWRkICgmc3RbaV0uZWx0LT52YWx1ZXMsIHN0W2ldLnZhbHVlLCBGY0ZhbHNlLCBsKTsKCQkgICAgYnJlYWs7CgkJfQoJCS8qIGZhbGwgdGhyb3VnaCAuLi4gKi8KCSAgICBjYXNlIEZjT3BQcmVwZW5kRmlyc3Q6CgkJRmNDb25maWdQYXR0ZXJuQWRkIChwLCBlLT5maWVsZCwgbCwgRmNGYWxzZSk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wQXBwZW5kOgoJCWlmICh0KQoJCXsKCQkgICAgRmNDb25maWdBZGQgKCZzdFtpXS5lbHQtPnZhbHVlcywgc3RbaV0udmFsdWUsIEZjVHJ1ZSwgbCk7CgkJICAgIGJyZWFrOwoJCX0KCQkvKiBmYWxsIHRocm91Z2ggLi4uICovCgkgICAgY2FzZSBGY09wQXBwZW5kTGFzdDoKCQlGY0NvbmZpZ1BhdHRlcm5BZGQgKHAsIGUtPmZpZWxkLCBsLCBGY1RydWUpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJfQoJLyoKCSAqIE5vdyBnbyB0aHJvdWdoIHRoZSBwYXR0ZXJuIGFuZCBlbGltaW5hdGUKCSAqIGFueSBwcm9wZXJ0aWVzIHdpdGhvdXQgZGF0YQoJICovCglmb3IgKGUgPSBzLT5lZGl0OyBlOyBlID0gZS0+bmV4dCkKCSAgICBGY0NvbmZpZ1BhdHRlcm5DYW5vbiAocCwgZS0+ZmllbGQpOwoKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgl7CgkgICAgcHJpbnRmICgiRmNDb25maWdTdWJzdGl0dXRlIGVkaXQiKTsKCSAgICBGY1BhdHRlcm5QcmludCAocCk7Cgl9CiAgICB9CiAgICBGY01lbUZyZWUgKEZDX01FTV9TVUJTVEFURSwgY29uZmlnLT5tYXhPYmplY3RzICogc2l6ZW9mIChGY1N1YlN0YXRlKSk7CiAgICBmcmVlIChzdCk7CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiRmNDb25maWdTdWJzdGl0dXRlIGRvbmUiKTsKCUZjUGF0dGVyblByaW50IChwKTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY0NvbmZpZ1N1YnN0aXR1dGUgKEZjQ29uZmlnCSpjb25maWcsCgkJICAgIEZjUGF0dGVybgkqcCwKCQkgICAgRmNNYXRjaEtpbmQJa2luZCkKewogICAgcmV0dXJuIEZjQ29uZmlnU3Vic3RpdHV0ZVdpdGhQYXQgKGNvbmZpZywgcCwgMCwga2luZCk7Cn0KCiNpZm5kZWYgRk9OVENPTkZJR19QQVRICiNkZWZpbmUgRk9OVENPTkZJR19QQVRICSIvZXRjL2ZvbnRzIgojZW5kaWYKCiNpZm5kZWYgRk9OVENPTkZJR19GSUxFCiNkZWZpbmUgRk9OVENPTkZJR19GSUxFCSJmb250cy5jb25mIgojZW5kaWYKCnN0YXRpYyBGY0NoYXI4ICoKRmNDb25maWdGaWxlRXhpc3RzIChjb25zdCBGY0NoYXI4ICpkaXIsIGNvbnN0IEZjQ2hhcjggKmZpbGUpCnsKICAgIEZjQ2hhcjggICAgKnBhdGg7CgogICAgaWYgKCFkaXIpCglkaXIgPSAoRmNDaGFyOCAqKSAiIjsKICAgIHBhdGggPSBtYWxsb2MgKHN0cmxlbiAoKGNoYXIgKikgZGlyKSArIDEgKyBzdHJsZW4gKChjaGFyICopIGZpbGUpICsgMSk7CiAgICBpZiAoIXBhdGgpCglyZXR1cm4gMDsKCiAgICBzdHJjcHkgKChjaGFyICopIHBhdGgsIChjb25zdCBjaGFyICopIGRpcik7CiAgICAvKiBtYWtlIHN1cmUgdGhlcmUncyBhIHNpbmdsZSBzZXBhcmF0aW5nIC8gKi8KICAgIGlmICgoIXBhdGhbMF0gfHwgcGF0aFtzdHJsZW4oKGNoYXIgKikgcGF0aCktMV0gIT0gJy8nKSAmJiBmaWxlWzBdICE9ICcvJykKCXN0cmNhdCAoKGNoYXIgKikgcGF0aCwgIi8iKTsKICAgIHN0cmNhdCAoKGNoYXIgKikgcGF0aCwgKGNoYXIgKikgZmlsZSk7CgogICAgaWYgKGFjY2VzcyAoKGNoYXIgKikgcGF0aCwgUl9PSykgPT0gMCkKCXJldHVybiBwYXRoOwogICAgCiAgICBmcmVlIChwYXRoKTsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgRmNDaGFyOCAqKgpGY0NvbmZpZ0dldFBhdGggKHZvaWQpCnsKICAgIEZjQ2hhcjggICAgKipwYXRoOwogICAgRmNDaGFyOCAgICAqZW52LCAqZSwgKmNvbG9uOwogICAgRmNDaGFyOCAgICAqZGlyOwogICAgaW50CSAgICBucGF0aDsKICAgIGludAkgICAgaTsKCiAgICBucGF0aCA9IDI7CS8qIGRlZmF1bHQgZGlyICsgbnVsbCAqLwogICAgZW52ID0gKEZjQ2hhcjggKikgZ2V0ZW52ICgiRk9OVENPTkZJR19QQVRIIik7CiAgICBpZiAoZW52KQogICAgewoJZSA9IGVudjsKCW5wYXRoKys7Cgl3aGlsZSAoKmUpCgkgICAgaWYgKCplKysgPT0gJzonKQoJCW5wYXRoKys7CiAgICB9CiAgICBwYXRoID0gY2FsbG9jIChucGF0aCwgc2l6ZW9mIChGY0NoYXI4ICopKTsKICAgIGlmICghcGF0aCkKCWdvdG8gYmFpbDA7CiAgICBpID0gMDsKCiAgICBpZiAoZW52KQogICAgewoJZSA9IGVudjsKCXdoaWxlICgqZSkgCgl7CgkgICAgY29sb24gPSAoRmNDaGFyOCAqKSBzdHJjaHIgKChjaGFyICopIGUsICc6Jyk7CgkgICAgaWYgKCFjb2xvbikKCQljb2xvbiA9IGUgKyBzdHJsZW4gKChjaGFyICopIGUpOwoJICAgIHBhdGhbaV0gPSBtYWxsb2MgKGNvbG9uIC0gZSArIDEpOwoJICAgIGlmICghcGF0aFtpXSkKCQlnb3RvIGJhaWwxOwoJICAgIHN0cm5jcHkgKChjaGFyICopIHBhdGhbaV0sIChjb25zdCBjaGFyICopIGUsIGNvbG9uIC0gZSk7CgkgICAgcGF0aFtpXVtjb2xvbiAtIGVdID0gJ1wwJzsKCSAgICBpZiAoKmNvbG9uKQoJCWUgPSBjb2xvbiArIDE7CgkgICAgZWxzZQoJCWUgPSBjb2xvbjsKCSAgICBpKys7Cgl9CiAgICB9CiAgICAKICAgIGRpciA9IChGY0NoYXI4ICopIEZPTlRDT05GSUdfUEFUSDsKICAgIHBhdGhbaV0gPSBtYWxsb2MgKHN0cmxlbiAoKGNoYXIgKikgZGlyKSArIDEpOwogICAgaWYgKCFwYXRoW2ldKQoJZ290byBiYWlsMTsKICAgIHN0cmNweSAoKGNoYXIgKikgcGF0aFtpXSwgKGNvbnN0IGNoYXIgKikgZGlyKTsKICAgIHJldHVybiBwYXRoOwoKYmFpbDE6CiAgICBmb3IgKGkgPSAwOyBwYXRoW2ldOyBpKyspCglmcmVlIChwYXRoW2ldKTsKICAgIGZyZWUgKHBhdGgpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgdm9pZApGY0NvbmZpZ0ZyZWVQYXRoIChGY0NoYXI4ICoqcGF0aCkKewogICAgRmNDaGFyOCAgICAqKnA7CgogICAgZm9yIChwID0gcGF0aDsgKnA7IHArKykKCWZyZWUgKCpwKTsKICAgIGZyZWUgKHBhdGgpOwp9CgpGY0NoYXI4ICoKRmNDb25maWdGaWxlbmFtZSAoY29uc3QgRmNDaGFyOCAqdXJsKQp7CiAgICBGY0NoYXI4ICAgICpmaWxlLCAqZGlyLCAqKnBhdGgsICoqcDsKICAgIAogICAgaWYgKCF1cmwgfHwgISp1cmwpCiAgICB7Cgl1cmwgPSAoRmNDaGFyOCAqKSBnZXRlbnYgKCJGT05UQ09ORklHX0ZJTEUiKTsKCWlmICghdXJsKQoJICAgIHVybCA9IChGY0NoYXI4ICopIEZPTlRDT05GSUdfRklMRTsKICAgIH0KICAgIGZpbGUgPSAwOwogICAgc3dpdGNoICgqdXJsKSB7CiAgICBjYXNlICd+JzoKCWRpciA9IChGY0NoYXI4ICopIGdldGVudiAoIkhPTUUiKTsKCWlmIChkaXIpCgkgICAgZmlsZSA9IEZjQ29uZmlnRmlsZUV4aXN0cyAoZGlyLCB1cmwgKyAxKTsKCWVsc2UKCSAgICBmaWxlID0gMDsKCWJyZWFrOwogICAgY2FzZSAnLyc6CglmaWxlID0gRmNDb25maWdGaWxlRXhpc3RzICgwLCB1cmwpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJcGF0aCA9IEZjQ29uZmlnR2V0UGF0aCAoKTsKCWlmICghcGF0aCkKCSAgICByZXR1cm4gMDsKCWZvciAocCA9IHBhdGg7ICpwOyBwKyspCgl7CgkgICAgZmlsZSA9IEZjQ29uZmlnRmlsZUV4aXN0cyAoKnAsIHVybCk7CgkgICAgaWYgKGZpbGUpCgkJYnJlYWs7Cgl9CglGY0NvbmZpZ0ZyZWVQYXRoIChwYXRoKTsKCWJyZWFrOwogICAgfQogICAgcmV0dXJuIGZpbGU7Cn0KCi8qCiAqIE1hbmFnZSB0aGUgYXBwbGljYXRpb24tc3BlY2lmaWMgZm9udHMKICovCgpGY0Jvb2wKRmNDb25maWdBcHBGb250QWRkRmlsZSAoRmNDb25maWcgICAgKmNvbmZpZywKCQkJY29uc3QgRmNDaGFyOCAgKmZpbGUpCnsKICAgIEZjRm9udFNldAkqc2V0OwogICAgRmNTdHJTZXQJKnN1YmRpcnM7CiAgICBGY1N0ckxpc3QJKnN1Ymxpc3Q7CiAgICBGY0NoYXI4CSpzdWJkaXI7CgogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KCiAgICBzdWJkaXJzID0gRmNTdHJTZXRDcmVhdGUgKCk7CiAgICBpZiAoIXN1YmRpcnMpCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgc2V0ID0gRmNDb25maWdHZXRGb250cyAoY29uZmlnLCBGY1NldEFwcGxpY2F0aW9uKTsKICAgIGlmICghc2V0KQogICAgewoJc2V0ID0gRmNGb250U2V0Q3JlYXRlICgpOwoJaWYgKCFzZXQpCgl7CgkgICAgRmNTdHJTZXREZXN0cm95IChzdWJkaXJzKTsKCSAgICByZXR1cm4gRmNGYWxzZTsKCX0KCUZjQ29uZmlnU2V0Rm9udHMgKGNvbmZpZywgc2V0LCBGY1NldEFwcGxpY2F0aW9uKTsKICAgIH0KCQogICAgaWYgKCFGY0ZpbGVTY2FuIChzZXQsIHN1YmRpcnMsIDAsIGNvbmZpZy0+YmxhbmtzLCBmaWxlLCBGY0ZhbHNlKSkKICAgIHsKCUZjU3RyU2V0RGVzdHJveSAoc3ViZGlycyk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGlmICgoc3VibGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoc3ViZGlycykpKQogICAgewoJd2hpbGUgKChzdWJkaXIgPSBGY1N0ckxpc3ROZXh0IChzdWJsaXN0KSkpCgl7CgkgICAgRmNDb25maWdBcHBGb250QWRkRGlyIChjb25maWcsIHN1YmRpcik7Cgl9CglGY1N0ckxpc3REb25lIChzdWJsaXN0KTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY0NvbmZpZ0FwcEZvbnRBZGREaXIgKEZjQ29uZmlnCSAgICAqY29uZmlnLAoJCSAgICAgICBjb25zdCBGY0NoYXI4ICAgKmRpcikKewogICAgRmNGb250U2V0CSpzZXQ7CiAgICBGY1N0clNldAkqc3ViZGlyczsKICAgIEZjU3RyTGlzdAkqc3VibGlzdDsKICAgIEZjQ2hhcjgJKnN1YmRpcjsKICAgIAogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHN1YmRpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghc3ViZGlycykKCXJldHVybiBGY0ZhbHNlOwogICAgCiAgICBzZXQgPSBGY0NvbmZpZ0dldEZvbnRzIChjb25maWcsIEZjU2V0QXBwbGljYXRpb24pOwogICAgaWYgKCFzZXQpCiAgICB7CglzZXQgPSBGY0ZvbnRTZXRDcmVhdGUgKCk7CglpZiAoIXNldCkKCXsKCSAgICBGY1N0clNldERlc3Ryb3kgKHN1YmRpcnMpOwoJICAgIHJldHVybiBGY0ZhbHNlOwoJfQoJRmNDb25maWdTZXRGb250cyAoY29uZmlnLCBzZXQsIEZjU2V0QXBwbGljYXRpb24pOwogICAgfQogICAgCiAgICBpZiAoIUZjRGlyU2NhbiAoc2V0LCBzdWJkaXJzLCAwLCBjb25maWctPmJsYW5rcywgZGlyLCBGY0ZhbHNlKSkKICAgIHsKCUZjU3RyU2V0RGVzdHJveSAoc3ViZGlycyk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGlmICgoc3VibGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoc3ViZGlycykpKQogICAgewoJd2hpbGUgKChzdWJkaXIgPSBGY1N0ckxpc3ROZXh0IChzdWJsaXN0KSkpCgl7CgkgICAgRmNDb25maWdBcHBGb250QWRkRGlyIChjb25maWcsIHN1YmRpcik7Cgl9CglGY1N0ckxpc3REb25lIChzdWJsaXN0KTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnZvaWQKRmNDb25maWdBcHBGb250Q2xlYXIgKEZjQ29uZmlnCSAgICAqY29uZmlnKQp7CiAgICBGY0NvbmZpZ1NldEZvbnRzIChjb25maWcsIDAsIEZjU2V0QXBwbGljYXRpb24pOwp9Cg==