LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2NmZy5jLHYgMS4xNSAyMDAyLzA2LzIxIDA2OjE0OjQ1IGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKCkZjQ29uZmlnICAgICpfZmNDb25maWc7CgpGY0NvbmZpZyAqCkZjQ29uZmlnQ3JlYXRlICh2b2lkKQp7CiAgICBGY1NldE5hbWUJc2V0OwogICAgRmNDb25maWcJKmNvbmZpZzsKCiAgICBjb25maWcgPSBtYWxsb2MgKHNpemVvZiAoRmNDb25maWcpKTsKICAgIGlmICghY29uZmlnKQoJZ290byBiYWlsMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9DT05GSUcsIHNpemVvZiAoRmNDb25maWcpKTsKICAgIAogICAgY29uZmlnLT5jb25maWdEaXJzID0gRmNTdHJTZXRDcmVhdGUgKCk7CiAgICBpZiAoIWNvbmZpZy0+Y29uZmlnRGlycykKCWdvdG8gYmFpbDE7CiAgICAKICAgIGNvbmZpZy0+Y29uZmlnRmlsZXMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghY29uZmlnLT5jb25maWdGaWxlcykKCWdvdG8gYmFpbDI7CiAgICAKICAgIGNvbmZpZy0+Zm9udERpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKICAgIGlmICghY29uZmlnLT5mb250RGlycykKCWdvdG8gYmFpbDM7CiAgICAKICAgIGNvbmZpZy0+Y2FjaGUgPSAwOwogICAgaWYgKCFGY0NvbmZpZ1NldENhY2hlIChjb25maWcsIChGY0NoYXI4ICopICgifi8iIEZDX1VTRVJfQ0FDSEVfRklMRSkpKQoJZ290byBiYWlsNDsKCiAgICBjb25maWctPmJsYW5rcyA9IDA7CgogICAgY29uZmlnLT5zdWJzdFBhdHRlcm4gPSAwOwogICAgY29uZmlnLT5zdWJzdEZvbnQgPSAwOwogICAgY29uZmlnLT5tYXhPYmplY3RzID0gMDsKICAgIGZvciAoc2V0ID0gRmNTZXRTeXN0ZW07IHNldCA8PSBGY1NldEFwcGxpY2F0aW9uOyBzZXQrKykKCWNvbmZpZy0+Zm9udHNbc2V0XSA9IDA7CgogICAgY29uZmlnLT5yZXNjYW5UaW1lID0gdGltZSgwKTsKICAgIGNvbmZpZy0+cmVzY2FuSW50ZXJ2YWwgPSAzMDsgICAgCiAgICAKICAgIHJldHVybiBjb25maWc7CgpiYWlsNDoKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5mb250RGlycyk7CmJhaWwzOgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmNvbmZpZ0ZpbGVzKTsKYmFpbDI6CiAgICBGY1N0clNldERlc3Ryb3kgKGNvbmZpZy0+Y29uZmlnRGlycyk7CmJhaWwxOgogICAgZnJlZSAoY29uZmlnKTsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0NPTkZJRywgc2l6ZW9mIChGY0NvbmZpZykpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNGaWxlVGltZSB7CiAgICB0aW1lX3QgIHRpbWU7CiAgICBGY0Jvb2wgIHNldDsKfSBGY0ZpbGVUaW1lOwoKc3RhdGljIEZjRmlsZVRpbWUKRmNDb25maWdOZXdlc3RGaWxlIChGY1N0clNldCAqZmlsZXMpCnsKICAgIEZjU3RyTGlzdAkgICAgKmxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGZpbGVzKTsKICAgIEZjRmlsZVRpbWUJICAgIG5ld2VzdCA9IHsgMCwgRmNGYWxzZSB9OwogICAgRmNDaGFyOAkgICAgKmZpbGU7CiAgICBzdHJ1Y3QgIHN0YXQgICAgc3RhdGI7CgogICAgaWYgKGxpc3QpCiAgICB7Cgl3aGlsZSAoKGZpbGUgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgkgICAgaWYgKHN0YXQgKChjaGFyICopIGZpbGUsICZzdGF0YikgPT0gMCkKCQlpZiAoIW5ld2VzdC5zZXQgfHwgc3RhdGIuc3RfbXRpbWUgLSBuZXdlc3QudGltZSA+IDApCgkJICAgIG5ld2VzdC50aW1lID0gc3RhdGIuc3RfbXRpbWU7CglGY1N0ckxpc3REb25lIChsaXN0KTsKICAgIH0KICAgIHJldHVybiBuZXdlc3Q7Cn0KCkZjQm9vbApGY0NvbmZpZ1VwdG9EYXRlIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY0ZpbGVUaW1lCWNvbmZpZ190aW1lLCBmb250X3RpbWU7CiAgICB0aW1lX3QJbm93ID0gdGltZSgwKTsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBjb25maWdfdGltZSA9IEZjQ29uZmlnTmV3ZXN0RmlsZSAoY29uZmlnLT5jb25maWdGaWxlcyk7CiAgICBmb250X3RpbWUgPSBGY0NvbmZpZ05ld2VzdEZpbGUgKGNvbmZpZy0+Y29uZmlnRGlycyk7CiAgICBpZiAoKGNvbmZpZ190aW1lLnNldCAmJiBjb25maWdfdGltZS50aW1lIC0gY29uZmlnLT5yZXNjYW5UaW1lID4gMCkgfHwKCShmb250X3RpbWUuc2V0ICYmIGZvbnRfdGltZS50aW1lIC0gY29uZmlnLT5yZXNjYW5UaW1lKSA+IDApCiAgICB7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGNvbmZpZy0+cmVzY2FuVGltZSA9IG5vdzsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyB2b2lkCkZjU3Vic3REZXN0cm95IChGY1N1YnN0ICpzKQp7CiAgICBGY1N1YnN0ICpuOwogICAgCiAgICB3aGlsZSAocykKICAgIHsKCW4gPSBzLT5uZXh0OwoJRmNUZXN0RGVzdHJveSAocy0+dGVzdCk7CglGY0VkaXREZXN0cm95IChzLT5lZGl0KTsKCXMgPSBuOwogICAgfQp9Cgp2b2lkCkZjQ29uZmlnRGVzdHJveSAoRmNDb25maWcgKmNvbmZpZykKewogICAgRmNTZXROYW1lCXNldDsKCiAgICBpZiAoY29uZmlnID09IF9mY0NvbmZpZykKCV9mY0NvbmZpZyA9IDA7CgogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmNvbmZpZ0RpcnMpOwogICAgRmNTdHJTZXREZXN0cm95IChjb25maWctPmZvbnREaXJzKTsKICAgIEZjU3RyU2V0RGVzdHJveSAoY29uZmlnLT5jb25maWdGaWxlcyk7CgogICAgRmNTdHJGcmVlIChjb25maWctPmNhY2hlKTsKCiAgICBGY1N1YnN0RGVzdHJveSAoY29uZmlnLT5zdWJzdFBhdHRlcm4pOwogICAgRmNTdWJzdERlc3Ryb3kgKGNvbmZpZy0+c3Vic3RGb250KTsKICAgIGZvciAoc2V0ID0gRmNTZXRTeXN0ZW07IHNldCA8PSBGY1NldEFwcGxpY2F0aW9uOyBzZXQrKykKCWlmIChjb25maWctPmZvbnRzW3NldF0pCgkgICAgRmNGb250U2V0RGVzdHJveSAoY29uZmlnLT5mb250c1tzZXRdKTsKICAgIGZyZWUgKGNvbmZpZyk7CiAgICBGY01lbUZyZWUgKEZDX01FTV9DT05GSUcsIHNpemVvZiAoRmNDb25maWcpKTsKfQoKLyoKICogU2NhbiB0aGUgY3VycmVudCBsaXN0IG9mIGRpcmVjdG9yaWVzIGluIHRoZSBjb25maWd1cmF0aW9uCiAqIGFuZCBidWlsZCB0aGUgc2V0IG9mIGF2YWlsYWJsZSBmb250cy4gVXBkYXRlIHRoZQogKiBwZXItdXNlciBjYWNoZSBmaWxlIHRvIHJlZmxlY3QgdGhlIG5ldyBjb25maWd1cmF0aW9uCiAqLwoKRmNCb29sCkZjQ29uZmlnQnVpbGRGb250cyAoRmNDb25maWcgKmNvbmZpZykKewogICAgRmNGb250U2V0CSAgICAqZm9udHM7CiAgICBGY0dsb2JhbENhY2hlICAgKmNhY2hlOwogICAgRmNTdHJMaXN0CSAgICAqbGlzdDsKICAgIEZjQ2hhcjgJICAgICpkaXI7CgogICAgZm9udHMgPSBGY0ZvbnRTZXRDcmVhdGUgKCk7CiAgICBpZiAoIWZvbnRzKQoJZ290byBiYWlsMDsKICAgIAogICAgY2FjaGUgPSBGY0dsb2JhbENhY2hlQ3JlYXRlICgpOwogICAgaWYgKCFjYWNoZSkKCWdvdG8gYmFpbDE7CgogICAgRmNHbG9iYWxDYWNoZUxvYWQgKGNhY2hlLCBjb25maWctPmNhY2hlKTsKCiAgICBsaXN0ID0gRmNDb25maWdHZXRGb250RGlycyAoY29uZmlnKTsKICAgIGlmICghbGlzdCkKCWdvdG8gYmFpbDE7CgogICAgd2hpbGUgKChkaXIgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19GT05UU0VUKQoJICAgIHByaW50ZiAoInNjYW4gZGlyICVzXG4iLCBkaXIpOwoJRmNEaXJTY2FuIChmb250cywgY29uZmlnLT5mb250RGlycywgY2FjaGUsIGNvbmZpZy0+YmxhbmtzLCBkaXIsIEZjRmFsc2UpOwogICAgfQogICAgCiAgICBGY1N0ckxpc3REb25lIChsaXN0KTsKICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRk9OVFNFVCkKCUZjRm9udFNldFByaW50IChmb250cyk7CgogICAgRmNHbG9iYWxDYWNoZVNhdmUgKGNhY2hlLCBjb25maWctPmNhY2hlKTsKICAgIEZjR2xvYmFsQ2FjaGVEZXN0cm95IChjYWNoZSk7CgogICAgRmNDb25maWdTZXRGb250cyAoY29uZmlnLCBmb250cywgRmNTZXRTeXN0ZW0pOwogICAgCiAgICByZXR1cm4gRmNUcnVlOwpiYWlsMToKICAgIEZjRm9udFNldERlc3Ryb3kgKGZvbnRzKTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNCb29sCkZjQ29uZmlnU2V0Q3VycmVudCAoRmNDb25maWcgKmNvbmZpZykKewogICAgaWYgKCFjb25maWctPmZvbnRzKQoJaWYgKCFGY0NvbmZpZ0J1aWxkRm9udHMgKGNvbmZpZykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CgogICAgaWYgKF9mY0NvbmZpZykKCUZjQ29uZmlnRGVzdHJveSAoX2ZjQ29uZmlnKTsKICAgIF9mY0NvbmZpZyA9IGNvbmZpZzsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQ29uZmlnICoKRmNDb25maWdHZXRDdXJyZW50ICh2b2lkKQp7CiAgICBpZiAoIV9mY0NvbmZpZykKCWlmICghRmNJbml0ICgpKQoJICAgIHJldHVybiAwOwogICAgcmV0dXJuIF9mY0NvbmZpZzsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQ29uZmlnRGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICBjb25zdCBGY0NoYXI4ICpkKQp7CiAgICByZXR1cm4gRmNTdHJTZXRBZGRGaWxlbmFtZSAoY29uZmlnLT5jb25maWdEaXJzLCBkKTsKfQoKRmNTdHJMaXN0ICoKRmNDb25maWdHZXRDb25maWdEaXJzIChGY0NvbmZpZyAgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gRmNTdHJMaXN0Q3JlYXRlIChjb25maWctPmNvbmZpZ0RpcnMpOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRGb250RGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgY29uc3QgRmNDaGFyOCAgICpkKQp7CiAgICByZXR1cm4gRmNTdHJTZXRBZGRGaWxlbmFtZSAoY29uZmlnLT5mb250RGlycywgZCk7Cn0KCkZjQm9vbApGY0NvbmZpZ0FkZERpciAoRmNDb25maWcJICAgICpjb25maWcsCgkJY29uc3QgRmNDaGFyOAkgICAgKmQpCnsKICAgIHJldHVybiAoRmNDb25maWdBZGRDb25maWdEaXIgKGNvbmZpZywgZCkgJiYgCgkgICAgRmNDb25maWdBZGRGb250RGlyIChjb25maWcsIGQpKTsKfQoKRmNTdHJMaXN0ICoKRmNDb25maWdHZXRGb250RGlycyAoRmNDb25maWcJKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBGY1N0ckxpc3RDcmVhdGUgKGNvbmZpZy0+Zm9udERpcnMpOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRDb25maWdGaWxlIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICAgY29uc3QgRmNDaGFyOCAgICpmKQp7CiAgICBGY0Jvb2wJcmV0OwogICAgRmNDaGFyOAkqZmlsZSA9IEZjQ29uZmlnRmlsZW5hbWUgKGYpOwogICAgCiAgICBpZiAoIWZpbGUpCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgcmV0ID0gRmNTdHJTZXRBZGQgKGNvbmZpZy0+Y29uZmlnRmlsZXMsIGZpbGUpOwogICAgRmNTdHJGcmVlIChmaWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCkZjU3RyTGlzdCAqCkZjQ29uZmlnR2V0Q29uZmlnRmlsZXMgKEZjQ29uZmlnICAgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gRmNTdHJMaXN0Q3JlYXRlIChjb25maWctPmNvbmZpZ0ZpbGVzKTsKfQoKRmNCb29sCkZjQ29uZmlnU2V0Q2FjaGUgKEZjQ29uZmlnCSpjb25maWcsCgkJICBjb25zdCBGY0NoYXI4CSpjKQp7CiAgICBGY0NoYXI4ICAgICpuZXcgPSBGY1N0ckNvcHlGaWxlbmFtZSAoYyk7CiAgICAKICAgIGlmICghbmV3KQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoY29uZmlnLT5jYWNoZSkKCUZjU3RyRnJlZSAoY29uZmlnLT5jYWNoZSk7CiAgICBjb25maWctPmNhY2hlID0gbmV3OwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNDaGFyOCAqCkZjQ29uZmlnR2V0Q2FjaGUgKEZjQ29uZmlnICAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+Y2FjaGU7Cn0KCkZjRm9udFNldCAqCkZjQ29uZmlnR2V0Rm9udHMgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY1NldE5hbWUJc2V0KQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+Zm9udHNbc2V0XTsKfQoKdm9pZApGY0NvbmZpZ1NldEZvbnRzIChGY0NvbmZpZwkqY29uZmlnLAoJCSAgRmNGb250U2V0CSpmb250cywKCQkgIEZjU2V0TmFtZQlzZXQpCnsKICAgIGlmIChjb25maWctPmZvbnRzW3NldF0pCglGY0ZvbnRTZXREZXN0cm95IChjb25maWctPmZvbnRzW3NldF0pOwogICAgY29uZmlnLT5mb250c1tzZXRdID0gZm9udHM7Cn0KCgoKRmNCbGFua3MgKgpGY0NvbmZpZ0dldEJsYW5rcyAoRmNDb25maWcJKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmJsYW5rczsKfQoKRmNCb29sCkZjQ29uZmlnQWRkQmxhbmsgKEZjQ29uZmlnCSpjb25maWcsCgkJICBGY0NoYXIzMiAgICAJYmxhbmspCnsKICAgIEZjQmxhbmtzCSpiOwogICAgCiAgICBiID0gY29uZmlnLT5ibGFua3M7CiAgICBpZiAoIWIpCiAgICB7CgliID0gRmNCbGFua3NDcmVhdGUgKCk7CglpZiAoIWIpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoIUZjQmxhbmtzQWRkIChiLCBibGFuaykpCglyZXR1cm4gRmNGYWxzZTsKICAgIGNvbmZpZy0+YmxhbmtzID0gYjsKICAgIHJldHVybiBGY1RydWU7Cn0KCmludApGY0NvbmZpZ0dldFJlc2NhbkludmVydmFsIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+cmVzY2FuSW50ZXJ2YWw7Cn0KCkZjQm9vbApGY0NvbmZpZ1NldFJlc2NhbkludmVydmFsIChGY0NvbmZpZyAqY29uZmlnLCBpbnQgcmVzY2FuSW50ZXJ2YWwpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBjb25maWctPnJlc2NhbkludGVydmFsID0gcmVzY2FuSW50ZXJ2YWw7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRFZGl0IChGY0NvbmZpZwkqY29uZmlnLAoJCSBGY1Rlc3QJCSp0ZXN0LAoJCSBGY0VkaXQJCSplZGl0LAoJCSBGY01hdGNoS2luZAlraW5kKQp7CiAgICBGY1N1YnN0CSpzdWJzdCwgKipwcmV2OwogICAgRmNUZXN0CSp0OwogICAgaW50CQludW07CgogICAgc3Vic3QgPSAoRmNTdWJzdCAqKSBtYWxsb2MgKHNpemVvZiAoRmNTdWJzdCkpOwogICAgaWYgKCFzdWJzdCkKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGtpbmQgPT0gRmNNYXRjaFBhdHRlcm4pCglwcmV2ID0gJmNvbmZpZy0+c3Vic3RQYXR0ZXJuOwogICAgZWxzZQoJcHJldiA9ICZjb25maWctPnN1YnN0Rm9udDsKICAgIGZvciAoOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KTsKICAgICpwcmV2ID0gc3Vic3Q7CiAgICBzdWJzdC0+bmV4dCA9IDA7CiAgICBzdWJzdC0+dGVzdCA9IHRlc3Q7CiAgICBzdWJzdC0+ZWRpdCA9IGVkaXQ7CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiQWRkIFN1YnN0ICIpOwoJRmNTdWJzdFByaW50IChzdWJzdCk7CiAgICB9CiAgICBudW0gPSAwOwogICAgZm9yICh0ID0gdGVzdDsgdDsgdCA9IHQtPm5leHQpCgludW0rKzsKICAgIGlmIChjb25maWctPm1heE9iamVjdHMgPCBudW0pCgljb25maWctPm1heE9iamVjdHMgPSBudW07CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNTdWJTdGF0ZSB7CiAgICBGY1BhdHRlcm5FbHQgICAqZWx0OwogICAgRmNWYWx1ZUxpc3QgICAgKnZhbHVlOwp9IEZjU3ViU3RhdGU7CgpzdGF0aWMgRmNWYWx1ZQpGY0NvbmZpZ1Byb21vdGUgKEZjVmFsdWUgdiwgRmNWYWx1ZSB1KQp7CiAgICBpZiAodi50eXBlID09IEZjVHlwZUludGVnZXIpCiAgICB7Cgl2LnR5cGUgPSBGY1R5cGVEb3VibGU7Cgl2LnUuZCA9IChkb3VibGUpIHYudS5pOwogICAgfQogICAgZWxzZSBpZiAodi50eXBlID09IEZjVHlwZVZvaWQgJiYgdS50eXBlID09IEZjVHlwZU1hdHJpeCkKICAgIHsKCXYudS5tID0gJkZjSWRlbnRpdHlNYXRyaXg7Cgl2LnR5cGUgPSBGY1R5cGVNYXRyaXg7CiAgICB9CiAgICByZXR1cm4gdjsKfQoKRmNCb29sCkZjQ29uZmlnQ29tcGFyZVZhbHVlIChGY1ZhbHVlCW0sCgkJICAgICAgRmNPcAlvcCwKCQkgICAgICBGY1ZhbHVlCXYpCnsKICAgIEZjQm9vbCAgICByZXQgPSBGY0ZhbHNlOwogICAgCiAgICBtID0gRmNDb25maWdQcm9tb3RlIChtLCB2KTsKICAgIHYgPSBGY0NvbmZpZ1Byb21vdGUgKHYsIG0pOwogICAgaWYgKG0udHlwZSA9PSB2LnR5cGUpIAogICAgewoJcmV0ID0gRmNGYWxzZTsKCXN3aXRjaCAobS50eXBlKSB7CgljYXNlIEZjVHlwZUludGVnZXI6CgkgICAgYnJlYWs7CS8qIEZjQ29uZmlnUHJvbW90ZSBwcmV2ZW50cyB0aGlzIGZyb20gaGFwcGVuaW5nICovCgljYXNlIEZjVHlwZURvdWJsZToKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gbS51LmQgPT0gdi51LmQ7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6ICAgIAoJCXJldCA9IG0udS5kICE9IHYudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcExlc3M6ICAgIAoJCXJldCA9IG0udS5kIDwgdi51LmQ7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTGVzc0VxdWFsOiAgICAKCQlyZXQgPSBtLnUuZCA8PSB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BNb3JlOiAgICAKCQlyZXQgPSBtLnUuZCA+IHYudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE1vcmVFcXVhbDogICAgCgkJcmV0ID0gbS51LmQgPj0gdi51LmQ7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZUJvb2w6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOiAgICAKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBtLnUuYiA9PSB2LnUuYjsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDogICAgCgkJcmV0ID0gbS51LmIgIT0gdi51LmI7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZVN0cmluZzoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6ICAgIAoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCXJldCA9IEZjU3RyQ21wSWdub3JlQ2FzZSAobS51LnMsIHYudS5zKSA9PSAwOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOiAgICAKCQlyZXQgPSBGY1N0ckNtcElnbm9yZUNhc2UgKG0udS5zLCB2LnUucykgIT0gMDsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlTWF0cml4OgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBGY01hdHJpeEVxdWFsIChtLnUubSwgdi51Lm0pOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJCXJldCA9ICFGY01hdHJpeEVxdWFsIChtLnUubSwgdi51Lm0pOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVDaGFyU2V0OgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQkvKiBtIGNvbnRhaW5zIHYgaWYgdiBpcyBhIHN1YnNldCBvZiBtICovCgkJcmV0ID0gRmNDaGFyU2V0SXNTdWJzZXQgKHYudS5jLCBtLnUuYyk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkJcmV0ID0gRmNDaGFyU2V0RXF1YWwgKG0udS5jLCB2LnUuYyk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkJcmV0ID0gIUZjQ2hhclNldEVxdWFsIChtLnUuYywgdi51LmMpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVWb2lkOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBGY1RydWU7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZUZURmFjZToKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkJcmV0ID0gbS51LmYgPT0gdi51LmY7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkJcmV0ID0gbS51LmYgIT0gdi51LmY7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAob3AgPT0gRmNPcE5vdEVxdWFsKQoJICAgIHJldCA9IEZjVHJ1ZTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCgpzdGF0aWMgRmNWYWx1ZQpGY0NvbmZpZ0V2YWx1YXRlIChGY1BhdHRlcm4gKnAsIEZjRXhwciAqZSkKewogICAgRmNWYWx1ZQl2LCB2bCwgdnI7CiAgICBGY1Jlc3VsdAlyOwogICAgRmNNYXRyaXgJKm07CiAgICAKICAgIHN3aXRjaCAoZS0+b3ApIHsKICAgIGNhc2UgRmNPcEludGVnZXI6Cgl2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJdi51LmkgPSBlLT51Lml2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcERvdWJsZToKCXYudHlwZSA9IEZjVHlwZURvdWJsZTsKCXYudS5kID0gZS0+dS5kdmFsOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BTdHJpbmc6Cgl2LnR5cGUgPSBGY1R5cGVTdHJpbmc7Cgl2LnUucyA9IGUtPnUuc3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcE1hdHJpeDoKCXYudHlwZSA9IEZjVHlwZU1hdHJpeDsKCXYudS5tID0gZS0+dS5tdmFsOwoJdiA9IEZjVmFsdWVTYXZlICh2KTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ2hhclNldDoKCXYudHlwZSA9IEZjVHlwZUNoYXJTZXQ7Cgl2LnUuYyA9IGUtPnUuY3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcEJvb2w6Cgl2LnR5cGUgPSBGY1R5cGVCb29sOwoJdi51LmIgPSBlLT51LmJ2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcEZpZWxkOgoJciA9IEZjUGF0dGVybkdldCAocCwgZS0+dS5maWVsZCwgMCwgJnYpOwoJaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDb25zdDoKCWlmIChGY05hbWVDb25zdGFudCAoZS0+dS5jb25zdGFudCwgJnYudS5pKSkKCSAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNPcFF1ZXN0OgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7CglpZiAodmwudHlwZSA9PSBGY1R5cGVCb29sKQoJewoJICAgIGlmICh2bC51LmIpCgkJdiA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5yaWdodC0+dS50cmVlLmxlZnQpOwoJICAgIGVsc2UKCQl2ID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0LT51LnRyZWUucmlnaHQpOwoJfQoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BPcjoKICAgIGNhc2UgRmNPcEFuZDoKICAgIGNhc2UgRmNPcEVxdWFsOgogICAgY2FzZSBGY09wQ29udGFpbnM6CiAgICBjYXNlIEZjT3BOb3RFcXVhbDoKICAgIGNhc2UgRmNPcExlc3M6CiAgICBjYXNlIEZjT3BMZXNzRXF1YWw6CiAgICBjYXNlIEZjT3BNb3JlOgogICAgY2FzZSBGY09wTW9yZUVxdWFsOgogICAgY2FzZSBGY09wUGx1czoKICAgIGNhc2UgRmNPcE1pbnVzOgogICAgY2FzZSBGY09wVGltZXM6CiAgICBjYXNlIEZjT3BEaXZpZGU6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCXZyID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0KTsKCXZsID0gRmNDb25maWdQcm9tb3RlICh2bCwgdnIpOwoJdnIgPSBGY0NvbmZpZ1Byb21vdGUgKHZyLCB2bCk7CglpZiAodmwudHlwZSA9PSB2ci50eXBlKQoJewoJICAgIHN3aXRjaCAodmwudHlwZSkgewoJICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BQbHVzOgkgICAKCQkgICAgdi50eXBlID0gRmNUeXBlRG91YmxlOwoJCSAgICB2LnUuZCA9IHZsLnUuZCArIHZyLnUuZDsgCgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcE1pbnVzOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CgkJICAgIHYudS5kID0gdmwudS5kIC0gdnIudS5kOyAKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wVGltZXM6CgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgKiB2ci51LmQ7IAoJCSAgICBicmVhazsKCQljYXNlIEZjT3BEaXZpZGU6CgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgLyB2ci51LmQ7IAoJCSAgICBicmVhazsKCQljYXNlIEZjT3BFcXVhbDoKCQljYXNlIEZjT3BDb250YWluczoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsgCgkJICAgIHYudS5iID0gdmwudS5kID09IHZyLnUuZDsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6ICAgIAoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOyAKCQkgICAgdi51LmIgPSB2bC51LmQgIT0gdnIudS5kOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BMZXNzOiAgICAKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsgCgkJICAgIHYudS5iID0gdmwudS5kIDwgdnIudS5kOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BMZXNzRXF1YWw6ICAgIAoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOyAKCQkgICAgdi51LmIgPSB2bC51LmQgPD0gdnIudS5kOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BNb3JlOiAgICAKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsgCgkJICAgIHYudS5iID0gdmwudS5kID4gdnIudS5kOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BNb3JlRXF1YWw6ICAgIAoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOyAKCQkgICAgdi51LmIgPSB2bC51LmQgPj0gdnIudS5kOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOyAKCQkgICAgYnJlYWs7CgkJfQoJCWlmICh2LnR5cGUgPT0gRmNUeXBlRG91YmxlICYmCgkJICAgIHYudS5kID09IChkb3VibGUpIChpbnQpIHYudS5kKQoJCXsKCQkgICAgdi50eXBlID0gRmNUeXBlSW50ZWdlcjsKCQkgICAgdi51LmkgPSAoaW50KSB2LnUuZDsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY1R5cGVCb29sOgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BPcjoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSB2bC51LmIgfHwgdnIudS5iOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BBbmQ6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gdmwudS5iICYmIHZyLnUuYjsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wRXF1YWw6CgkJY2FzZSBGY09wQ29udGFpbnM6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gdmwudS5iID09IHZyLnUuYjsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gdmwudS5iICE9IHZyLnUuYjsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsgCgkJICAgIGJyZWFrOwoJCX0KCQlicmVhazsKCSAgICBjYXNlIEZjVHlwZVN0cmluZzoKCQlzd2l0Y2ggKGUtPm9wKSB7CgkJY2FzZSBGY09wRXF1YWw6CgkJY2FzZSBGY09wQ29udGFpbnM6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNTdHJDbXBJZ25vcmVDYXNlICh2bC51LnMsIHZyLnUucykgPT0gMDsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNTdHJDbXBJZ25vcmVDYXNlICh2bC51LnMsIHZyLnUucykgIT0gMDsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wUGx1czoKCQkgICAgdi50eXBlID0gRmNUeXBlU3RyaW5nOwoJCSAgICB2LnUucyA9IEZjU3RyUGx1cyAodmwudS5zLCB2ci51LnMpOwoJCSAgICBpZiAoIXYudS5zKQoJCQl2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY1R5cGVNYXRyaXg6CgkJc3dpdGNoIChlLT5vcCkgewoJCWNhc2UgRmNPcEVxdWFsOgoJCWNhc2UgRmNPcENvbnRhaW5zOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwoJCSAgICB2LnUuYiA9IEZjTWF0cml4RXF1YWwgKHZsLnUubSwgdnIudS5tKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNNYXRyaXhFcXVhbCAodmwudS5tLCB2ci51Lm0pOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BUaW1lczoKCQkgICAgdi50eXBlID0gRmNUeXBlTWF0cml4OwoJCSAgICBtID0gbWFsbG9jIChzaXplb2YgKEZjTWF0cml4KSk7CgkJICAgIGlmIChtKQoJCSAgICB7CgkJCUZjTWVtQWxsb2MgKEZDX01FTV9NQVRSSVgsIHNpemVvZiAoRmNNYXRyaXgpKTsKCQkJRmNNYXRyaXhNdWx0aXBseSAobSwgdmwudS5tLCB2ci51Lm0pOwoJCQl2LnUubSA9IG07CgkJICAgIH0KCQkgICAgZWxzZQoJCSAgICB7CgkJCXYudHlwZSA9IEZjVHlwZVZvaWQ7CgkJICAgIH0KCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCQkgICAgYnJlYWs7CgkJfQoJCWJyZWFrOwoJICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCQlzd2l0Y2ggKGUtPm9wKSB7CgkJY2FzZSBGY09wQ29udGFpbnM6CgkJICAgIC8qIHZsIGNvbnRhaW5zIHZyIGlmIHZyIGlzIGEgc3Vic2V0IG9mIHZsICovCgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNDaGFyU2V0SXNTdWJzZXQgKHZyLnUuYywgdmwudS5jKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wRXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNDaGFyU2V0RXF1YWwgKHZsLnUuYywgdnIudS5jKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gIUZjQ2hhclNldEVxdWFsICh2bC51LmMsIHZyLnUuYyk7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CgkJICAgIGJyZWFrOwoJCX0KCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCXYudHlwZSA9IEZjVHlwZVZvaWQ7CgkJYnJlYWs7CgkgICAgfQoJfQoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJRmNWYWx1ZURlc3Ryb3kgKHZyKTsKCWJyZWFrOwogICAgY2FzZSBGY09wTm90OgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7Cglzd2l0Y2ggKHZsLnR5cGUpIHsKCWNhc2UgRmNUeXBlQm9vbDoKCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwoJICAgIHYudS5iID0gIXZsLnUuYjsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCSAgICBicmVhazsKCX0KCUZjVmFsdWVEZXN0cm95ICh2bCk7CglicmVhazsKICAgIGRlZmF1bHQ6Cgl2LnR5cGUgPSBGY1R5cGVWb2lkOwoJYnJlYWs7CiAgICB9CiAgICByZXR1cm4gdjsKfQoKc3RhdGljIEZjVmFsdWVMaXN0ICoKRmNDb25maWdNYXRjaFZhbHVlTGlzdCAoRmNQYXR0ZXJuCSpwLAoJCQlGY1Rlc3QJCSp0LAoJCQlGY1ZhbHVlTGlzdAkqdmFsdWVzKQp7CiAgICBGY1ZhbHVlTGlzdAkgICAgKnJldCA9IDA7CiAgICBGY0V4cHIJICAgICplID0gdC0+ZXhwcjsKICAgIEZjVmFsdWUJICAgIHZhbHVlOwogICAgRmNWYWx1ZUxpc3QJICAgICp2OwogICAgCiAgICB3aGlsZSAoZSkKICAgIHsKCWlmIChlLT5vcCA9PSBGY09wQ29tbWEpCgl7CgkgICAgdmFsdWUgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7CgkgICAgZSA9IGUtPnUudHJlZS5yaWdodDsKCX0KCWVsc2UKCXsKCSAgICB2YWx1ZSA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUpOwoJICAgIGUgPSAwOwoJfQoKCWZvciAodiA9IHZhbHVlczsgdjsgdiA9IHYtPm5leHQpCgl7CgkgICAgaWYgKEZjQ29uZmlnQ29tcGFyZVZhbHVlICh2LT52YWx1ZSwgdC0+b3AsIHZhbHVlKSkKCSAgICB7CgkJaWYgKCFyZXQpCgkJICAgIHJldCA9IHY7CgkgICAgfQoJICAgIGVsc2UKCSAgICB7CgkJaWYgKHQtPnF1YWwgPT0gRmNRdWFsQWxsKQoJCXsKCQkgICAgcmV0ID0gMDsKCQkgICAgYnJlYWs7CgkJfQoJICAgIH0KCX0KCUZjVmFsdWVEZXN0cm95ICh2YWx1ZSk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgRmNWYWx1ZUxpc3QgKgpGY0NvbmZpZ1ZhbHVlcyAoRmNQYXR0ZXJuICpwLCBGY0V4cHIgKmUpCnsKICAgIEZjVmFsdWVMaXN0CSpsOwogICAgCiAgICBpZiAoIWUpCglyZXR1cm4gMDsKICAgIGwgPSAoRmNWYWx1ZUxpc3QgKikgbWFsbG9jIChzaXplb2YgKEZjVmFsdWVMaXN0KSk7CiAgICBpZiAoIWwpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9WQUxMSVNULCBzaXplb2YgKEZjVmFsdWVMaXN0KSk7CiAgICBpZiAoZS0+b3AgPT0gRmNPcENvbW1hKQogICAgewoJbC0+dmFsdWUgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7CglsLT5uZXh0ICA9IEZjQ29uZmlnVmFsdWVzIChwLCBlLT51LnRyZWUucmlnaHQpOwogICAgfQogICAgZWxzZQogICAgewoJbC0+dmFsdWUgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlKTsKCWwtPm5leHQgID0gMDsKICAgIH0KICAgIGwtPmJpbmRpbmcgPSBGY1ZhbHVlQmluZGluZ1dlYWs7CiAgICB3aGlsZSAobCAmJiBsLT52YWx1ZS50eXBlID09IEZjVHlwZVZvaWQpCiAgICB7CglGY1ZhbHVlTGlzdAkqbmV4dCA9IGwtPm5leHQ7CgkKCUZjTWVtRnJlZSAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKCWZyZWUgKGwpOwoJbCA9IG5leHQ7CiAgICB9CiAgICByZXR1cm4gbDsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ0FkZCAoRmNWYWx1ZUxpc3QgICAgKipoZWFkLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqcG9zaXRpb24sCgkgICAgIEZjQm9vbAkgICAgYXBwZW5kLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqbmV3KQp7CiAgICBGY1ZhbHVlTGlzdCAgICAqKnByZXYsICpsYXN0OwogICAgCiAgICBpZiAoYXBwZW5kKQogICAgewoJaWYgKHBvc2l0aW9uKQoJICAgIHByZXYgPSAmcG9zaXRpb24tPm5leHQ7CgllbHNlCgkgICAgZm9yIChwcmV2ID0gaGVhZDsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKCQk7CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAocG9zaXRpb24pCgl7CgkgICAgZm9yIChwcmV2ID0gaGVhZDsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKCSAgICB7CgkJaWYgKCpwcmV2ID09IHBvc2l0aW9uKQoJCSAgICBicmVhazsKCSAgICB9Cgl9CgllbHNlCgkgICAgcHJldiA9IGhlYWQ7CgoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCXsKCSAgICBpZiAoISpwcmV2KQoJCXByaW50ZiAoInBvc2l0aW9uIG5vdCBvbiBsaXN0XG4iKTsKCX0KICAgIH0KCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiJXMgbGlzdCBiZWZvcmUgIiwgYXBwZW5kID8gIkFwcGVuZCIgOiAiUHJlcGVuZCIpOwoJRmNWYWx1ZUxpc3RQcmludCAoKmhlYWQpOwoJcHJpbnRmICgiXG4iKTsKICAgIH0KICAgIAogICAgaWYgKG5ldykKICAgIHsKCWxhc3QgPSBuZXc7Cgl3aGlsZSAobGFzdC0+bmV4dCkKCSAgICBsYXN0ID0gbGFzdC0+bmV4dDsKICAgIAoJbGFzdC0+bmV4dCA9ICpwcmV2OwoJKnByZXYgPSBuZXc7CiAgICB9CiAgICAKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCIlcyBsaXN0IGFmdGVyICIsIGFwcGVuZCA/ICJBcHBlbmQiIDogIlByZXBlbmQiKTsKCUZjVmFsdWVMaXN0UHJpbnQgKCpoZWFkKTsKCXByaW50ZiAoIlxuIik7CiAgICB9CiAgICAKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnRGVsIChGY1ZhbHVlTGlzdCAgICAqKmhlYWQsCgkgICAgIEZjVmFsdWVMaXN0ICAgICpwb3NpdGlvbikKewogICAgRmNWYWx1ZUxpc3QgICAgKipwcmV2OwoKICAgIGZvciAocHJldiA9IGhlYWQ7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpCiAgICB7CglpZiAoKnByZXYgPT0gcG9zaXRpb24pCgl7CgkgICAgKnByZXYgPSBwb3NpdGlvbi0+bmV4dDsKCSAgICBwb3NpdGlvbi0+bmV4dCA9IDA7CgkgICAgRmNWYWx1ZUxpc3REZXN0cm95IChwb3NpdGlvbik7CgkgICAgYnJlYWs7Cgl9CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnUGF0dGVybkFkZCAoRmNQYXR0ZXJuCSpwLAoJCSAgICBjb25zdCBjaGFyCSpvYmplY3QsCgkJICAgIEZjVmFsdWVMaXN0CSpsaXN0LAoJCSAgICBGY0Jvb2wJYXBwZW5kKQp7CiAgICBpZiAobGlzdCkKICAgIHsKCUZjUGF0dGVybkVsdCAgICAqZSA9IEZjUGF0dGVybkluc2VydEVsdCAocCwgb2JqZWN0KTsKICAgIAoJaWYgKCFlKQoJICAgIHJldHVybjsKCUZjQ29uZmlnQWRkICgmZS0+dmFsdWVzLCAwLCBhcHBlbmQsIGxpc3QpOwogICAgfQp9CgovKgogKiBEZWxldGUgYWxsIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGggYSBmaWVsZAogKi8Kc3RhdGljIHZvaWQKRmNDb25maWdQYXR0ZXJuRGVsIChGY1BhdHRlcm4JKnAsCgkJICAgIGNvbnN0IGNoYXIJKm9iamVjdCkKewogICAgRmNQYXR0ZXJuRWx0ICAgICplID0gRmNQYXR0ZXJuRmluZEVsdCAocCwgb2JqZWN0KTsKICAgIGlmICghZSkKCXJldHVybjsKICAgIHdoaWxlIChlLT52YWx1ZXMpCglGY0NvbmZpZ0RlbCAoJmUtPnZhbHVlcywgZS0+dmFsdWVzKTsKfQoKc3RhdGljIHZvaWQKRmNDb25maWdQYXR0ZXJuQ2Fub24gKEZjUGF0dGVybgkgICAgKnAsCgkJICAgICAgY29uc3QgY2hhciAgICAqb2JqZWN0KQp7CiAgICBGY1BhdHRlcm5FbHQgICAgKmUgPSBGY1BhdHRlcm5GaW5kRWx0IChwLCBvYmplY3QpOwogICAgaWYgKCFlKQoJcmV0dXJuOwogICAgaWYgKCFlLT52YWx1ZXMpCglGY1BhdHRlcm5EZWwgKHAsIG9iamVjdCk7Cn0KCkZjQm9vbApGY0NvbmZpZ1N1YnN0aXR1dGUgKEZjQ29uZmlnCSpjb25maWcsCgkJICAgIEZjUGF0dGVybgkqcCwKCQkgICAgRmNNYXRjaEtpbmQJa2luZCkKewogICAgRmNTdWJzdAkgICAgKnM7CiAgICBGY1N1YlN0YXRlCSAgICAqc3Q7CiAgICBpbnQJCSAgICBpOwogICAgRmNUZXN0CSAgICAqdDsKICAgIEZjRWRpdAkgICAgKmU7CiAgICBGY1ZhbHVlTGlzdAkgICAgKmw7CgogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KCiAgICBzdCA9IChGY1N1YlN0YXRlICopIG1hbGxvYyAoY29uZmlnLT5tYXhPYmplY3RzICogc2l6ZW9mIChGY1N1YlN0YXRlKSk7CiAgICBpZiAoIXN0ICYmIGNvbmZpZy0+bWF4T2JqZWN0cykKCXJldHVybiBGY0ZhbHNlOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1NVQlNUQVRFLCBjb25maWctPm1heE9iamVjdHMgKiBzaXplb2YgKEZjU3ViU3RhdGUpKTsKCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiRmNDb25maWdTdWJzdGl0dXRlICIpOwoJRmNQYXR0ZXJuUHJpbnQgKHApOwogICAgfQogICAgaWYgKGtpbmQgPT0gRmNNYXRjaFBhdHRlcm4pCglzID0gY29uZmlnLT5zdWJzdFBhdHRlcm47CiAgICBlbHNlCglzID0gY29uZmlnLT5zdWJzdEZvbnQ7CiAgICBmb3IgKDsgczsgcyA9IHMtPm5leHQpCiAgICB7CgkvKgoJICogQ2hlY2sgdGhlIHRlc3RzIHRvIHNlZSBpZgoJICogdGhleSBhbGwgbWF0Y2ggdGhlIHBhdHRlcm4KCSAqLwoJZm9yICh0ID0gcy0+dGVzdCwgaSA9IDA7IHQ7IHQgPSB0LT5uZXh0LCBpKyspCgl7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCSAgICB7CgkJcHJpbnRmICgiRmNDb25maWdTdWJzdGl0dXRlIHRlc3QgIik7CgkJRmNUZXN0UHJpbnQgKHQpOwoJICAgIH0KCSAgICBzdFtpXS5lbHQgPSBGY1BhdHRlcm5GaW5kRWx0IChwLCB0LT5maWVsZCk7CgkgICAgLyoKCSAgICAgKiBJZiB0aGVyZSdzIG5vIHN1Y2ggZmllbGQgaW4gdGhlIGZvbnQsCgkgICAgICogdGhlbiBGY1F1YWxBbGwgbWF0Y2hlcyB3aGlsZSBGY1F1YWxBbnkgZG9lcyBub3QKCSAgICAgKi8KCSAgICBpZiAoIXN0W2ldLmVsdCkKCSAgICB7CgkJaWYgKHQtPnF1YWwgPT0gRmNRdWFsQWxsKQoJCXsKCQkgICAgc3RbaV0udmFsdWUgPSAwOwoJCSAgICBjb250aW51ZTsKCQl9CgkJZWxzZQoJCSAgICBicmVhazsKCSAgICB9CgkgICAgLyoKCSAgICAgKiBDaGVjayB0byBzZWUgaWYgdGhlcmUgaXMgYSBtYXRjaCwgbWFyayB0aGUgbG9jYXRpb24KCSAgICAgKiB0byBhcHBseSBtYXRjaC1yZWxhdGl2ZSBlZGl0cwoJICAgICAqLwoJICAgIHN0W2ldLnZhbHVlID0gRmNDb25maWdNYXRjaFZhbHVlTGlzdCAocCwgdCwgc3RbaV0uZWx0LT52YWx1ZXMpOwoJICAgIGlmICghc3RbaV0udmFsdWUpCgkJYnJlYWs7CgkgICAgaWYgKHQtPnF1YWwgPT0gRmNRdWFsRmlyc3QgJiYgc3RbaV0udmFsdWUgIT0gc3RbaV0uZWx0LT52YWx1ZXMpCgkJYnJlYWs7CgkgICAgaWYgKHQtPnF1YWwgPT0gRmNRdWFsTm90Rmlyc3QgJiYgc3RbaV0udmFsdWUgPT0gc3RbaV0uZWx0LT52YWx1ZXMpCgkJYnJlYWs7Cgl9CglpZiAodCkKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJCXByaW50ZiAoIk5vIG1hdGNoXG4iKTsKCSAgICBjb250aW51ZTsKCX0KCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgl7CgkgICAgcHJpbnRmICgiU3Vic3RpdHV0ZSAiKTsKCSAgICBGY1N1YnN0UHJpbnQgKHMpOwoJfQoJZm9yIChlID0gcy0+ZWRpdDsgZTsgZSA9IGUtPm5leHQpCgl7CgkgICAgLyoKCSAgICAgKiBFdmFsdWF0ZSB0aGUgbGlzdCBvZiBleHByZXNzaW9ucwoJICAgICAqLwoJICAgIGwgPSBGY0NvbmZpZ1ZhbHVlcyAocCwgZS0+ZXhwcik7CgkgICAgLyoKCSAgICAgKiBMb2NhdGUgYW55IHRlc3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZmllbGQKCSAgICAgKi8KCSAgICBmb3IgKHQgPSBzLT50ZXN0LCBpID0gMDsgdDsgdCA9IHQtPm5leHQsIGkrKykKCQlpZiAoIUZjU3RyQ21wSWdub3JlQ2FzZSAoKEZjQ2hhcjggKikgdC0+ZmllbGQsIChGY0NoYXI4ICopIGUtPmZpZWxkKSkKCQkgICAgYnJlYWs7CgkgICAgc3dpdGNoIChlLT5vcCkgewoJICAgIGNhc2UgRmNPcEFzc2lnbjoKCQkvKgoJCSAqIElmIHRoZXJlIHdhcyBhIHRlc3QsIHRoZW4gcmVwbGFjZSB0aGUgbWF0Y2hlZAoJCSAqIHZhbHVlIHdpdGggdGhlIG5ldyBsaXN0IG9mIHZhbHVlcwoJCSAqLwoJCWlmICh0KQoJCXsKCQkgICAgRmNWYWx1ZUxpc3QJKnRoaXNWYWx1ZSA9IHN0W2ldLnZhbHVlOwoJCSAgICBGY1ZhbHVlTGlzdAkqbmV4dFZhbHVlID0gdGhpc1ZhbHVlID8gdGhpc1ZhbHVlLT5uZXh0IDogMDsKCQkgICAgCgkJICAgIC8qCgkJICAgICAqIEFwcGVuZCB0aGUgbmV3IGxpc3Qgb2YgdmFsdWVzIGFmdGVyIHRoZSBjdXJyZW50IHZhbHVlCgkJICAgICAqLwoJCSAgICBGY0NvbmZpZ0FkZCAoJnN0W2ldLmVsdC0+dmFsdWVzLCB0aGlzVmFsdWUsIEZjVHJ1ZSwgbCk7CgkJICAgIC8qCgkJICAgICAqIERlbGV0ZSB0aGUgbWFya2VkIHZhbHVlCgkJICAgICAqLwoJCSAgICBGY0NvbmZpZ0RlbCAoJnN0W2ldLmVsdC0+dmFsdWVzLCB0aGlzVmFsdWUpOwoJCSAgICAvKgoJCSAgICAgKiBBZGp1c3QgYW55IHBvaW50ZXJzIGludG8gdGhlIHZhbHVlIGxpc3QgdG8gZW5zdXJlCgkJICAgICAqIGZ1dHVyZSBlZGl0cyBvY2N1ciBhdCB0aGUgc2FtZSBwbGFjZQoJCSAgICAgKi8KCQkgICAgZm9yICh0ID0gcy0+dGVzdCwgaSA9IDA7IHQ7IHQgPSB0LT5uZXh0LCBpKyspCgkJICAgIHsKCQkJaWYgKHN0W2ldLnZhbHVlID09IHRoaXNWYWx1ZSkKCQkJICAgIHN0W2ldLnZhbHVlID0gbmV4dFZhbHVlOwoJCSAgICB9CgkJICAgIGJyZWFrOwoJCX0KCQkvKiBmYWxsIHRocm91Z2ggLi4uICovCgkgICAgY2FzZSBGY09wQXNzaWduUmVwbGFjZToKCQkvKgoJCSAqIERlbGV0ZSBhbGwgb2YgdGhlIHZhbHVlcyBhbmQgaW5zZXJ0CgkJICogdGhlIG5ldyBzZXQKCQkgKi8KCQlGY0NvbmZpZ1BhdHRlcm5EZWwgKHAsIGUtPmZpZWxkKTsKCQlGY0NvbmZpZ1BhdHRlcm5BZGQgKHAsIGUtPmZpZWxkLCBsLCBGY1RydWUpOwoJCS8qCgkJICogQWRqdXN0IGFueSBwb2ludGVycyBpbnRvIHRoZSB2YWx1ZSBsaXN0IGFzIHRoZXkgbm8KCQkgKiBsb25nZXIgcG9pbnQgdG8gYW55dGhpbmcgdmFsaWQKCQkgKi8KCQlpZiAodCkKCQl7CgkJICAgIEZjUGF0dGVybkVsdCAgICAqdGhpc0VsdCA9IHN0W2ldLmVsdDsKCQkgICAgZm9yICh0ID0gcy0+dGVzdCwgaSA9IDA7IHQ7IHQgPSB0LT5uZXh0LCBpKyspCgkJICAgIHsKCQkJaWYgKHN0W2ldLmVsdCA9PSB0aGlzRWx0KQoJCQkgICAgc3RbaV0udmFsdWUgPSAwOwoJCSAgICB9CgkJfQoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcFByZXBlbmQ6CgkJaWYgKHQpCgkJewoJCSAgICBGY0NvbmZpZ0FkZCAoJnN0W2ldLmVsdC0+dmFsdWVzLCBzdFtpXS52YWx1ZSwgRmNGYWxzZSwgbCk7CgkJICAgIGJyZWFrOwoJCX0KCQkvKiBmYWxsIHRocm91Z2ggLi4uICovCgkgICAgY2FzZSBGY09wUHJlcGVuZEZpcnN0OgoJCUZjQ29uZmlnUGF0dGVybkFkZCAocCwgZS0+ZmllbGQsIGwsIEZjRmFsc2UpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcEFwcGVuZDoKCQlpZiAodCkKCQl7CgkJICAgIEZjQ29uZmlnQWRkICgmc3RbaV0uZWx0LT52YWx1ZXMsIHN0W2ldLnZhbHVlLCBGY1RydWUsIGwpOwoJCSAgICBicmVhazsKCQl9CgkJLyogZmFsbCB0aHJvdWdoIC4uLiAqLwoJICAgIGNhc2UgRmNPcEFwcGVuZExhc3Q6CgkJRmNDb25maWdQYXR0ZXJuQWRkIChwLCBlLT5maWVsZCwgbCwgRmNUcnVlKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCX0KCS8qCgkgKiBOb3cgZ28gdGhyb3VnaCB0aGUgcGF0dGVybiBhbmQgZWxpbWluYXRlCgkgKiBhbnkgcHJvcGVydGllcyB3aXRob3V0IGRhdGEKCSAqLwoJZm9yIChlID0gcy0+ZWRpdDsgZTsgZSA9IGUtPm5leHQpCgkgICAgRmNDb25maWdQYXR0ZXJuQ2Fub24gKHAsIGUtPmZpZWxkKTsKCglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJewoJICAgIHByaW50ZiAoIkZjQ29uZmlnU3Vic3RpdHV0ZSBlZGl0Iik7CgkgICAgRmNQYXR0ZXJuUHJpbnQgKHApOwoJfQogICAgfQogICAgRmNNZW1GcmVlIChGQ19NRU1fU1VCU1RBVEUsIGNvbmZpZy0+bWF4T2JqZWN0cyAqIHNpemVvZiAoRmNTdWJTdGF0ZSkpOwogICAgZnJlZSAoc3QpOwogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIkZjQ29uZmlnU3Vic3RpdHV0ZSBkb25lIik7CglGY1BhdHRlcm5QcmludCAocCk7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgojaWZuZGVmIEZPTlRDT05GSUdfUEFUSAojZGVmaW5lIEZPTlRDT05GSUdfUEFUSAkiL2V0Yy9mb250cyIKI2VuZGlmCgojaWZuZGVmIEZPTlRDT05GSUdfRklMRQojZGVmaW5lIEZPTlRDT05GSUdfRklMRQkiZm9udHMuY29uZiIKI2VuZGlmCgpzdGF0aWMgRmNDaGFyOCAqCkZjQ29uZmlnRmlsZUV4aXN0cyAoY29uc3QgRmNDaGFyOCAqZGlyLCBjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBGY0NoYXI4ICAgICpwYXRoOwoKICAgIGlmICghZGlyKQoJZGlyID0gKEZjQ2hhcjggKikgIiI7CiAgICBwYXRoID0gbWFsbG9jIChzdHJsZW4gKChjaGFyICopIGRpcikgKyAxICsgc3RybGVuICgoY2hhciAqKSBmaWxlKSArIDEpOwogICAgaWYgKCFwYXRoKQoJcmV0dXJuIDA7CgogICAgc3RyY3B5ICgoY2hhciAqKSBwYXRoLCAoY29uc3QgY2hhciAqKSBkaXIpOwogICAgLyogbWFrZSBzdXJlIHRoZXJlJ3MgYSBzaW5nbGUgc2VwYXJhdGluZyAvICovCiAgICBpZiAoKCFwYXRoWzBdIHx8IHBhdGhbc3RybGVuKChjaGFyICopIHBhdGgpLTFdICE9ICcvJykgJiYgZmlsZVswXSAhPSAnLycpCglzdHJjYXQgKChjaGFyICopIHBhdGgsICIvIik7CiAgICBzdHJjYXQgKChjaGFyICopIHBhdGgsIChjaGFyICopIGZpbGUpOwoKICAgIGlmIChhY2Nlc3MgKChjaGFyICopIHBhdGgsIFJfT0spID09IDApCglyZXR1cm4gcGF0aDsKICAgIAogICAgZnJlZSAocGF0aCk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZjQ2hhcjggKioKRmNDb25maWdHZXRQYXRoICh2b2lkKQp7CiAgICBGY0NoYXI4ICAgICoqcGF0aDsKICAgIEZjQ2hhcjggICAgKmVudiwgKmUsICpjb2xvbjsKICAgIEZjQ2hhcjggICAgKmRpcjsKICAgIGludAkgICAgbnBhdGg7CiAgICBpbnQJICAgIGk7CgogICAgbnBhdGggPSAyOwkvKiBkZWZhdWx0IGRpciArIG51bGwgKi8KICAgIGVudiA9IChGY0NoYXI4ICopIGdldGVudiAoIkZPTlRDT05GSUdfUEFUSCIpOwogICAgaWYgKGVudikKICAgIHsKCWUgPSBlbnY7CglucGF0aCsrOwoJd2hpbGUgKCplKQoJICAgIGlmICgqZSsrID09ICc6JykKCQlucGF0aCsrOwogICAgfQogICAgcGF0aCA9IGNhbGxvYyAobnBhdGgsIHNpemVvZiAoRmNDaGFyOCAqKSk7CiAgICBpZiAoIXBhdGgpCglnb3RvIGJhaWwwOwogICAgaSA9IDA7CgogICAgaWYgKGVudikKICAgIHsKCWUgPSBlbnY7Cgl3aGlsZSAoKmUpIAoJewoJICAgIGNvbG9uID0gKEZjQ2hhcjggKikgc3RyY2hyICgoY2hhciAqKSBlLCAnOicpOwoJICAgIGlmICghY29sb24pCgkJY29sb24gPSBlICsgc3RybGVuICgoY2hhciAqKSBlKTsKCSAgICBwYXRoW2ldID0gbWFsbG9jIChjb2xvbiAtIGUgKyAxKTsKCSAgICBpZiAoIXBhdGhbaV0pCgkJZ290byBiYWlsMTsKCSAgICBzdHJuY3B5ICgoY2hhciAqKSBwYXRoW2ldLCAoY29uc3QgY2hhciAqKSBlLCBjb2xvbiAtIGUpOwoJICAgIHBhdGhbaV1bY29sb24gLSBlXSA9ICdcMCc7CgkgICAgaWYgKCpjb2xvbikKCQllID0gY29sb24gKyAxOwoJICAgIGVsc2UKCQllID0gY29sb247CgkgICAgaSsrOwoJfQogICAgfQogICAgCiAgICBkaXIgPSAoRmNDaGFyOCAqKSBGT05UQ09ORklHX1BBVEg7CiAgICBwYXRoW2ldID0gbWFsbG9jIChzdHJsZW4gKChjaGFyICopIGRpcikgKyAxKTsKICAgIGlmICghcGF0aFtpXSkKCWdvdG8gYmFpbDE7CiAgICBzdHJjcHkgKChjaGFyICopIHBhdGhbaV0sIChjb25zdCBjaGFyICopIGRpcik7CiAgICByZXR1cm4gcGF0aDsKCmJhaWwxOgogICAgZm9yIChpID0gMDsgcGF0aFtpXTsgaSsrKQoJZnJlZSAocGF0aFtpXSk7CiAgICBmcmVlIChwYXRoKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKRmNDb25maWdGcmVlUGF0aCAoRmNDaGFyOCAqKnBhdGgpCnsKICAgIEZjQ2hhcjggICAgKipwOwoKICAgIGZvciAocCA9IHBhdGg7ICpwOyBwKyspCglmcmVlICgqcCk7CiAgICBmcmVlIChwYXRoKTsKfQoKRmNDaGFyOCAqCkZjQ29uZmlnRmlsZW5hbWUgKGNvbnN0IEZjQ2hhcjggKnVybCkKewogICAgRmNDaGFyOCAgICAqZmlsZSwgKmRpciwgKipwYXRoLCAqKnA7CiAgICAKICAgIGlmICghdXJsIHx8ICEqdXJsKQogICAgewoJdXJsID0gKEZjQ2hhcjggKikgZ2V0ZW52ICgiRk9OVENPTkZJR19GSUxFIik7CglpZiAoIXVybCkKCSAgICB1cmwgPSAoRmNDaGFyOCAqKSBGT05UQ09ORklHX0ZJTEU7CiAgICB9CiAgICBmaWxlID0gMDsKICAgIHN3aXRjaCAoKnVybCkgewogICAgY2FzZSAnfic6CglkaXIgPSAoRmNDaGFyOCAqKSBnZXRlbnYgKCJIT01FIik7CglpZiAoZGlyKQoJICAgIGZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKGRpciwgdXJsICsgMSk7CgllbHNlCgkgICAgZmlsZSA9IDA7CglicmVhazsKICAgIGNhc2UgJy8nOgoJZmlsZSA9IEZjQ29uZmlnRmlsZUV4aXN0cyAoMCwgdXJsKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCXBhdGggPSBGY0NvbmZpZ0dldFBhdGggKCk7CglpZiAoIXBhdGgpCgkgICAgcmV0dXJuIDA7Cglmb3IgKHAgPSBwYXRoOyAqcDsgcCsrKQoJewoJICAgIGZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKCpwLCB1cmwpOwoJICAgIGlmIChmaWxlKQoJCWJyZWFrOwoJfQoJRmNDb25maWdGcmVlUGF0aCAocGF0aCk7CglicmVhazsKICAgIH0KICAgIHJldHVybiBmaWxlOwp9CgovKgogKiBNYW5hZ2UgdGhlIGFwcGxpY2F0aW9uLXNwZWNpZmljIGZvbnRzCiAqLwoKRmNCb29sCkZjQ29uZmlnQXBwRm9udEFkZEZpbGUgKEZjQ29uZmlnICAgICpjb25maWcsCgkJCWNvbnN0IEZjQ2hhcjggICpmaWxlKQp7CiAgICBGY0ZvbnRTZXQJKnNldDsKICAgIEZjU3RyU2V0CSpzdWJkaXJzOwogICAgRmNTdHJMaXN0CSpzdWJsaXN0OwogICAgRmNDaGFyOAkqc3ViZGlyOwoKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CgogICAgc3ViZGlycyA9IEZjU3RyU2V0Q3JlYXRlICgpOwogICAgaWYgKCFzdWJkaXJzKQoJcmV0dXJuIEZjRmFsc2U7CiAgICAKICAgIHNldCA9IEZjQ29uZmlnR2V0Rm9udHMgKGNvbmZpZywgRmNTZXRBcHBsaWNhdGlvbik7CiAgICBpZiAoIXNldCkKICAgIHsKCXNldCA9IEZjRm9udFNldENyZWF0ZSAoKTsKCWlmICghc2V0KQoJewoJICAgIEZjU3RyU2V0RGVzdHJveSAoc3ViZGlycyk7CgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl9CglGY0NvbmZpZ1NldEZvbnRzIChjb25maWcsIHNldCwgRmNTZXRBcHBsaWNhdGlvbik7CiAgICB9CgkKICAgIGlmICghRmNGaWxlU2NhbiAoc2V0LCBzdWJkaXJzLCAwLCBjb25maWctPmJsYW5rcywgZmlsZSwgRmNGYWxzZSkpCiAgICB7CglGY1N0clNldERlc3Ryb3kgKHN1YmRpcnMpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoKHN1Ymxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKHN1YmRpcnMpKSkKICAgIHsKCXdoaWxlICgoc3ViZGlyID0gRmNTdHJMaXN0TmV4dCAoc3VibGlzdCkpKQoJewoJICAgIEZjQ29uZmlnQXBwRm9udEFkZERpciAoY29uZmlnLCBzdWJkaXIpOwoJfQoJRmNTdHJMaXN0RG9uZSAoc3VibGlzdCk7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNDb25maWdBcHBGb250QWRkRGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICAgY29uc3QgRmNDaGFyOCAgICpkaXIpCnsKICAgIEZjRm9udFNldAkqc2V0OwogICAgRmNTdHJTZXQJKnN1YmRpcnM7CiAgICBGY1N0ckxpc3QJKnN1Ymxpc3Q7CiAgICBGY0NoYXI4CSpzdWJkaXI7CiAgICAKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBzdWJkaXJzID0gRmNTdHJTZXRDcmVhdGUgKCk7CiAgICBpZiAoIXN1YmRpcnMpCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgc2V0ID0gRmNDb25maWdHZXRGb250cyAoY29uZmlnLCBGY1NldEFwcGxpY2F0aW9uKTsKICAgIGlmICghc2V0KQogICAgewoJc2V0ID0gRmNGb250U2V0Q3JlYXRlICgpOwoJaWYgKCFzZXQpCgl7CgkgICAgRmNTdHJTZXREZXN0cm95IChzdWJkaXJzKTsKCSAgICByZXR1cm4gRmNGYWxzZTsKCX0KCUZjQ29uZmlnU2V0Rm9udHMgKGNvbmZpZywgc2V0LCBGY1NldEFwcGxpY2F0aW9uKTsKICAgIH0KICAgIAogICAgaWYgKCFGY0RpclNjYW4gKHNldCwgc3ViZGlycywgMCwgY29uZmlnLT5ibGFua3MsIGRpciwgRmNGYWxzZSkpCiAgICB7CglGY1N0clNldERlc3Ryb3kgKHN1YmRpcnMpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoKHN1Ymxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKHN1YmRpcnMpKSkKICAgIHsKCXdoaWxlICgoc3ViZGlyID0gRmNTdHJMaXN0TmV4dCAoc3VibGlzdCkpKQoJewoJICAgIEZjQ29uZmlnQXBwRm9udEFkZERpciAoY29uZmlnLCBzdWJkaXIpOwoJfQoJRmNTdHJMaXN0RG9uZSAoc3VibGlzdCk7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp2b2lkCkZjQ29uZmlnQXBwRm9udENsZWFyIChGY0NvbmZpZwkgICAgKmNvbmZpZykKewogICAgRmNDb25maWdTZXRGb250cyAoY29uZmlnLCAwLCBGY1NldEFwcGxpY2F0aW9uKTsKfQo=