LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2NmZy5jLHYgMS4yIDIwMDIvMDIvMTUgMDY6MDE6Mjcga2VpdGhwIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDAgS2VpdGggUGFja2FyZCwgbWVtYmVyIG9mIFRoZSBYRnJlZTg2IFByb2plY3QsIEluYy4KICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgImZjaW50LmgiCgpGY0NvbmZpZyAgICAqX2ZjQ29uZmlnOwoKRmNDb25maWcgKgpGY0NvbmZpZ0NyZWF0ZSAodm9pZCkKewogICAgRmNTZXROYW1lCXNldDsKICAgIEZjQ29uZmlnCSpjb25maWc7CgogICAgY29uZmlnID0gbWFsbG9jIChzaXplb2YgKEZjQ29uZmlnKSk7CiAgICBpZiAoIWNvbmZpZykKCWdvdG8gYmFpbDA7CiAgICAKICAgIGNvbmZpZy0+ZGlycyA9IG1hbGxvYyAoc2l6ZW9mIChjaGFyICopKTsKICAgIGlmICghY29uZmlnLT5kaXJzKQoJZ290byBiYWlsMTsKICAgIGNvbmZpZy0+ZGlyc1swXSA9IDA7CiAgICAKICAgIGNvbmZpZy0+Y29uZmlnRmlsZXMgPSBtYWxsb2MgKHNpemVvZiAoY2hhciAqKSk7CiAgICBpZiAoIWNvbmZpZy0+Y29uZmlnRmlsZXMpCglnb3RvIGJhaWwyOwogICAgY29uZmlnLT5jb25maWdGaWxlc1swXSA9IDA7CiAgICAKICAgIGNvbmZpZy0+Y2FjaGUgPSAwOwogICAgaWYgKCFGY0NvbmZpZ1NldENhY2hlIChjb25maWcsIChGY0NoYXI4ICopICgifi8iIEZDX1VTRVJfQ0FDSEVfRklMRSkpKQoJZ290byBiYWlsMzsKCiAgICBjb25maWctPmJsYW5rcyA9IDA7CgogICAgY29uZmlnLT5zdWJzdFBhdHRlcm4gPSAwOwogICAgY29uZmlnLT5zdWJzdEZvbnQgPSAwOwogICAgY29uZmlnLT5tYXhPYmplY3RzID0gMDsKICAgIGZvciAoc2V0ID0gRmNTZXRTeXN0ZW07IHNldCA8PSBGY1NldEFwcGxpY2F0aW9uOyBzZXQrKykKCWNvbmZpZy0+Zm9udHNbc2V0XSA9IDA7CiAgICAKICAgIHJldHVybiBjb25maWc7CgpiYWlsMzoKICAgIGZyZWUgKGNvbmZpZy0+Y29uZmlnRmlsZXMpOwpiYWlsMjoKICAgIGZyZWUgKGNvbmZpZy0+ZGlycyk7CmJhaWwxOgogICAgZnJlZSAoY29uZmlnKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKRmNTdWJzdERlc3Ryb3kgKEZjU3Vic3QgKnMpCnsKICAgIEZjU3Vic3QgKm47CiAgICAKICAgIHdoaWxlIChzKQogICAgewoJbiA9IHMtPm5leHQ7CglGY1Rlc3REZXN0cm95IChzLT50ZXN0KTsKCUZjRWRpdERlc3Ryb3kgKHMtPmVkaXQpOwoJcyA9IG47CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnRGVzdHJveVN0cmluZ3MgKEZjQ2hhcjggKipzdHJpbmdzKQp7CiAgICBGY0NoYXI4ICAgICoqczsKCiAgICBmb3IgKHMgPSBzdHJpbmdzOyBzICYmICpzOyBzKyspCglmcmVlICgqcyk7CiAgICBpZiAoc3RyaW5ncykKCWZyZWUgKHN0cmluZ3MpOwp9CiAgICAKc3RhdGljIEZjQm9vbApGY0NvbmZpZ0FkZFN0cmluZyAoRmNDaGFyOCAqKipzdHJpbmdzLCBGY0NoYXI4ICpzdHJpbmcpCnsKICAgIGludAkgICAgbjsKICAgIEZjQ2hhcjggICAgKipzOwogICAgCiAgICBuID0gMDsKICAgIGZvciAocyA9ICpzdHJpbmdzOyBzICYmICpzOyBzKyspCgluKys7CiAgICBzID0gbWFsbG9jICgobiArIDIpICogc2l6ZW9mIChGY0NoYXI4ICopKTsKICAgIGlmICghcykKCXJldHVybiBGY0ZhbHNlOwogICAgc1tuXSA9IHN0cmluZzsKICAgIHNbbisxXSA9IDA7CiAgICBtZW1jcHkgKHMsICpzdHJpbmdzLCBuICogc2l6ZW9mIChGY0NoYXI4ICopKTsKICAgIGZyZWUgKCpzdHJpbmdzKTsKICAgICpzdHJpbmdzID0gczsKICAgIHJldHVybiBGY1RydWU7Cn0KCnZvaWQKRmNDb25maWdEZXN0cm95IChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY1NldE5hbWUJc2V0OwogICAgRmNDb25maWdEZXN0cm95U3RyaW5ncyAoY29uZmlnLT5kaXJzKTsKICAgIEZjQ29uZmlnRGVzdHJveVN0cmluZ3MgKGNvbmZpZy0+Y29uZmlnRmlsZXMpOwoKICAgIGZyZWUgKGNvbmZpZy0+Y2FjaGUpOwoKICAgIEZjU3Vic3REZXN0cm95IChjb25maWctPnN1YnN0UGF0dGVybik7CiAgICBGY1N1YnN0RGVzdHJveSAoY29uZmlnLT5zdWJzdEZvbnQpOwogICAgZm9yIChzZXQgPSBGY1NldFN5c3RlbTsgc2V0IDw9IEZjU2V0QXBwbGljYXRpb247IHNldCsrKQoJaWYgKGNvbmZpZy0+Zm9udHNbc2V0XSkKCSAgICBGY0ZvbnRTZXREZXN0cm95IChjb25maWctPmZvbnRzW3NldF0pOwp9CgovKgogKiBTY2FuIHRoZSBjdXJyZW50IGxpc3Qgb2YgZGlyZWN0b3JpZXMgaW4gdGhlIGNvbmZpZ3VyYXRpb24KICogYW5kIGJ1aWxkIHRoZSBzZXQgb2YgYXZhaWxhYmxlIGZvbnRzLiBVcGRhdGUgdGhlCiAqIHBlci11c2VyIGNhY2hlIGZpbGUgdG8gcmVmbGVjdCB0aGUgbmV3IGNvbmZpZ3VyYXRpb24KICovCgpGY0Jvb2wKRmNDb25maWdCdWlsZEZvbnRzIChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY0ZvbnRTZXQgICAqZm9udHM7CiAgICBGY0ZpbGVDYWNoZSAqY2FjaGU7CiAgICBGY0NoYXI4CSoqZDsKCiAgICBmb250cyA9IEZjRm9udFNldENyZWF0ZSAoKTsKICAgIGlmICghZm9udHMpCglnb3RvIGJhaWwwOwogICAgCiAgICBjYWNoZSA9IEZjRmlsZUNhY2hlQ3JlYXRlICgpOwogICAgaWYgKCFjYWNoZSkKCWdvdG8gYmFpbDE7CgogICAgRmNGaWxlQ2FjaGVMb2FkIChjYWNoZSwgY29uZmlnLT5jYWNoZSk7CgogICAgZm9yIChkID0gY29uZmlnLT5kaXJzOyBkICYmICpkOyBkKyspCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19GT05UU0VUKQoJICAgIHByaW50ZiAoInNjYW4gZGlyICVzXG4iLCAqZCk7CglGY0RpclNjYW4gKGZvbnRzLCBjYWNoZSwgY29uZmlnLT5ibGFua3MsICpkLCBGY0ZhbHNlKTsKICAgIH0KICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRk9OVFNFVCkKCUZjRm9udFNldFByaW50IChmb250cyk7CgogICAgRmNGaWxlQ2FjaGVTYXZlIChjYWNoZSwgY29uZmlnLT5jYWNoZSk7CiAgICBGY0ZpbGVDYWNoZURlc3Ryb3kgKGNhY2hlKTsKCiAgICBGY0NvbmZpZ1NldEZvbnRzIChjb25maWcsIGZvbnRzLCBGY1NldFN5c3RlbSk7CiAgICAKICAgIHJldHVybiBGY1RydWU7CmJhaWwxOgogICAgRmNGb250U2V0RGVzdHJveSAoZm9udHMpOwpiYWlsMDoKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpGY0Jvb2wKRmNDb25maWdTZXRDdXJyZW50IChGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZy0+Zm9udHMpCglpZiAoIUZjQ29uZmlnQnVpbGRGb250cyAoY29uZmlnKSkKCSAgICByZXR1cm4gRmNGYWxzZTsKCiAgICBpZiAoX2ZjQ29uZmlnKQoJRmNDb25maWdEZXN0cm95IChfZmNDb25maWcpOwogICAgX2ZjQ29uZmlnID0gY29uZmlnOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNDb25maWcgKgpGY0NvbmZpZ0dldEN1cnJlbnQgKHZvaWQpCnsKICAgIGlmICghX2ZjQ29uZmlnKQoJaWYgKCFGY0luaXQgKCkpCgkgICAgcmV0dXJuIDA7CiAgICByZXR1cm4gX2ZjQ29uZmlnOwp9CgpGY0Jvb2wKRmNDb25maWdBZGREaXIgKEZjQ29uZmlnICAgICpjb25maWcsCgkJY29uc3QgRmNDaGFyOCAgKmQpCnsKICAgIEZjQ2hhcjggICAgKmRpcjsKICAgIEZjQ2hhcjggICAgKmg7CgogICAgaWYgKCpkID09ICd+JykKICAgIHsKCWggPSAoRmNDaGFyOCAqKSBnZXRlbnYgKCJIT01FIik7CglpZiAoIWgpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglkaXIgPSAoRmNDaGFyOCAqKSBtYWxsb2MgKHN0cmxlbiAoKGNoYXIgKikgaCkgKyBzdHJsZW4gKChjaGFyICopIGQpKTsKCWlmICghZGlyKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJc3RyY3B5ICgoY2hhciAqKSBkaXIsIChjaGFyICopIGgpOwoJc3RyY2F0ICgoY2hhciAqKSBkaXIsIChjaGFyICopIGQrMSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglkaXIgPSAoRmNDaGFyOCAqKSBtYWxsb2MgKHN0cmxlbiAoKGNoYXIgKikgZCkgKyAxKTsKCWlmICghZGlyKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJc3RyY3B5IChkaXIsIGQpOwogICAgfQogICAgaWYgKCFGY0NvbmZpZ0FkZFN0cmluZyAoJmNvbmZpZy0+ZGlycywgZGlyKSkKICAgIHsKCWZyZWUgKGRpcik7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQ2hhcjggKioKRmNDb25maWdHZXREaXJzIChGY0NvbmZpZyAgICpjb25maWcpCnsKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gY29uZmlnLT5kaXJzOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRDb25maWdGaWxlIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICAgY29uc3QgRmNDaGFyOCAgICpmKQp7CiAgICBGY0NoYXI4ICAgICpmaWxlOwogICAgZmlsZSA9IEZjQ29uZmlnRmlsZW5hbWUgKGYpOwogICAgaWYgKCFmaWxlKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoIUZjQ29uZmlnQWRkU3RyaW5nICgmY29uZmlnLT5jb25maWdGaWxlcywgZmlsZSkpCiAgICB7CglmcmVlIChmaWxlKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNDaGFyOCAqKgpGY0NvbmZpZ0dldENvbmZpZ0ZpbGVzIChGY0NvbmZpZyAgICAqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+Y29uZmlnRmlsZXM7Cn0KCkZjQm9vbApGY0NvbmZpZ1NldENhY2hlIChGY0NvbmZpZwkqY29uZmlnLAoJCSAgY29uc3QgRmNDaGFyOAkqYykKewogICAgRmNDaGFyOCAgICAqbmV3OwogICAgRmNDaGFyOCAgICAqaDsKCiAgICBpZiAoKmMgPT0gJ34nKQogICAgewoJaCA9IChGY0NoYXI4ICopIGdldGVudiAoIkhPTUUiKTsKCWlmICghaCkKCSAgICByZXR1cm4gRmNGYWxzZTsKCW5ldyA9IChGY0NoYXI4ICopIG1hbGxvYyAoc3RybGVuICgoY2hhciAqKSBoKSArIHN0cmxlbiAoKGNoYXIgKikgYykpOwoJaWYgKCFuZXcpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglzdHJjcHkgKChjaGFyICopIG5ldywgKGNoYXIgKikgaCk7CglzdHJjYXQgKChjaGFyICopIG5ldywgKGNoYXIgKikgYysxKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCW5ldyA9IEZjU3RyQ29weSAoYyk7CiAgICB9CiAgICBpZiAoY29uZmlnLT5jYWNoZSkKCWZyZWUgKGNvbmZpZy0+Y2FjaGUpOwogICAgY29uZmlnLT5jYWNoZSA9IG5ldzsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQ2hhcjggKgpGY0NvbmZpZ0dldENhY2hlIChGY0NvbmZpZyAgKmNvbmZpZykKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmNhY2hlOwp9CgpGY0ZvbnRTZXQgKgpGY0NvbmZpZ0dldEZvbnRzIChGY0NvbmZpZwkqY29uZmlnLAoJCSAgRmNTZXROYW1lCXNldCkKewogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBjb25maWctPmZvbnRzW3NldF07Cn0KCnZvaWQKRmNDb25maWdTZXRGb250cyAoRmNDb25maWcJKmNvbmZpZywKCQkgIEZjRm9udFNldAkqZm9udHMsCgkJICBGY1NldE5hbWUJc2V0KQp7CiAgICBpZiAoY29uZmlnLT5mb250c1tzZXRdKQoJRmNGb250U2V0RGVzdHJveSAoY29uZmlnLT5mb250c1tzZXRdKTsKICAgIGNvbmZpZy0+Zm9udHNbc2V0XSA9IGZvbnRzOwp9CgpGY0JsYW5rcyAqCkZjQ29uZmlnR2V0QmxhbmtzIChGY0NvbmZpZwkqY29uZmlnKQp7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIGNvbmZpZy0+YmxhbmtzOwp9CgpGY0Jvb2wKRmNDb25maWdBZGRCbGFuayAoRmNDb25maWcJKmNvbmZpZywKCQkgIEZjQ2hhcjMyICAgIAlibGFuaykKewogICAgRmNCbGFua3MJKmI7CiAgICAKICAgIGIgPSBjb25maWctPmJsYW5rczsKICAgIGlmICghYikKICAgIHsKCWIgPSBGY0JsYW5rc0NyZWF0ZSAoKTsKCWlmICghYikKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGlmICghRmNCbGFua3NBZGQgKGIsIGJsYW5rKSkKCXJldHVybiBGY0ZhbHNlOwogICAgY29uZmlnLT5ibGFua3MgPSBiOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjQ29uZmlnQWRkRWRpdCAoRmNDb25maWcJKmNvbmZpZywKCQkgRmNUZXN0CQkqdGVzdCwKCQkgRmNFZGl0CQkqZWRpdCwKCQkgRmNNYXRjaEtpbmQJa2luZCkKewogICAgRmNTdWJzdAkqc3Vic3QsICoqcHJldjsKICAgIEZjVGVzdAkqdDsKICAgIGludAkJbnVtOwoKICAgIHN1YnN0ID0gKEZjU3Vic3QgKikgbWFsbG9jIChzaXplb2YgKEZjU3Vic3QpKTsKICAgIGlmICghc3Vic3QpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChraW5kID09IEZjTWF0Y2hQYXR0ZXJuKQoJcHJldiA9ICZjb25maWctPnN1YnN0UGF0dGVybjsKICAgIGVsc2UKCXByZXYgPSAmY29uZmlnLT5zdWJzdEZvbnQ7CiAgICBmb3IgKDsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCk7CiAgICAqcHJldiA9IHN1YnN0OwogICAgc3Vic3QtPm5leHQgPSAwOwogICAgc3Vic3QtPnRlc3QgPSB0ZXN0OwogICAgc3Vic3QtPmVkaXQgPSBlZGl0OwogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIkFkZCBTdWJzdCAiKTsKCUZjU3Vic3RQcmludCAoc3Vic3QpOwogICAgfQogICAgbnVtID0gMDsKICAgIGZvciAodCA9IHRlc3Q7IHQ7IHQgPSB0LT5uZXh0KQoJbnVtKys7CiAgICBpZiAoY29uZmlnLT5tYXhPYmplY3RzIDwgbnVtKQoJY29uZmlnLT5tYXhPYmplY3RzID0gbnVtOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKdHlwZWRlZiBzdHJ1Y3QgX0ZjU3ViU3RhdGUgewogICAgRmNQYXR0ZXJuRWx0ICAgKmVsdDsKICAgIEZjVmFsdWVMaXN0ICAgICp2YWx1ZTsKfSBGY1N1YlN0YXRlOwoKc3RhdGljIGNvbnN0IEZjTWF0cml4ICAgIEZjSWRlbnRpdHlNYXRyaXggPSB7IDEsIDAsIDAsIDEgfTsKCnN0YXRpYyBGY1ZhbHVlCkZjQ29uZmlnUHJvbW90ZSAoRmNWYWx1ZSB2LCBGY1ZhbHVlIHUpCnsKICAgIGlmICh2LnR5cGUgPT0gRmNUeXBlSW50ZWdlcikKICAgIHsKCXYudHlwZSA9IEZjVHlwZURvdWJsZTsKCXYudS5kID0gKGRvdWJsZSkgdi51Lmk7CiAgICB9CiAgICBlbHNlIGlmICh2LnR5cGUgPT0gRmNUeXBlVm9pZCAmJiB1LnR5cGUgPT0gRmNUeXBlTWF0cml4KQogICAgewoJdi51Lm0gPSAoRmNNYXRyaXggKikgJkZjSWRlbnRpdHlNYXRyaXg7Cgl2LnR5cGUgPSBGY1R5cGVNYXRyaXg7CiAgICB9CiAgICByZXR1cm4gdjsKfQoKRmNCb29sCkZjQ29uZmlnQ29tcGFyZVZhbHVlIChGY1ZhbHVlCW0sCgkJICAgICAgRmNPcAlvcCwKCQkgICAgICBGY1ZhbHVlCXYpCnsKICAgIEZjQm9vbCAgICByZXQgPSBGY0ZhbHNlOwogICAgCiAgICBtID0gRmNDb25maWdQcm9tb3RlIChtLCB2KTsKICAgIHYgPSBGY0NvbmZpZ1Byb21vdGUgKHYsIG0pOwogICAgaWYgKG0udHlwZSA9PSB2LnR5cGUpIAogICAgewoJcmV0ID0gRmNGYWxzZTsKCXN3aXRjaCAobS50eXBlKSB7CgljYXNlIEZjVHlwZUludGVnZXI6CgkgICAgYnJlYWs7CS8qIEZjQ29uZmlnUHJvbW90ZSBwcmV2ZW50cyB0aGlzIGZyb20gaGFwcGVuaW5nICovCgljYXNlIEZjVHlwZURvdWJsZToKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkgICAgY2FzZSBGY09wQ29udGFpbnM6CgkJcmV0ID0gbS51LmQgPT0gdi51LmQ7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6ICAgIAoJCXJldCA9IG0udS5kICE9IHYudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcExlc3M6ICAgIAoJCXJldCA9IG0udS5kIDwgdi51LmQ7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTGVzc0VxdWFsOiAgICAKCQlyZXQgPSBtLnUuZCA8PSB2LnUuZDsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BNb3JlOiAgICAKCQlyZXQgPSBtLnUuZCA+IHYudS5kOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE1vcmVFcXVhbDogICAgCgkJcmV0ID0gbS51LmQgPj0gdi51LmQ7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZUJvb2w6CgkgICAgc3dpdGNoIChvcCkgewoJICAgIGNhc2UgRmNPcEVxdWFsOiAgICAKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBtLnUuYiA9PSB2LnUuYjsKCQlicmVhazsKCSAgICBjYXNlIEZjT3BOb3RFcXVhbDogICAgCgkJcmV0ID0gbS51LmIgIT0gdi51LmI7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZVN0cmluZzoKCSAgICBzd2l0Y2ggKG9wKSB7CgkgICAgY2FzZSBGY09wRXF1YWw6ICAgIAoJICAgIGNhc2UgRmNPcENvbnRhaW5zOgoJCXJldCA9IEZjU3RyQ21wSWdub3JlQ2FzZSAobS51LnMsIHYudS5zKSA9PSAwOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOiAgICAKCQlyZXQgPSBGY1N0ckNtcElnbm9yZUNhc2UgKG0udS5zLCB2LnUucykgIT0gMDsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgRmNUeXBlTWF0cml4OgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBGY01hdHJpeEVxdWFsIChtLnUubSwgdi51Lm0pOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcE5vdEVxdWFsOgoJCXJldCA9ICFGY01hdHJpeEVxdWFsIChtLnUubSwgdi51Lm0pOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVDaGFyU2V0OgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQkvKiBtIGNvbnRhaW5zIHYgaWYgdiAtIG0gaXMgZW1wdHkgKi8KCQlyZXQgPSBGY0NoYXJTZXRTdWJ0cmFjdENvdW50ICh2LnUuYywgbS51LmMpID09IDA7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wRXF1YWw6CgkJcmV0ID0gRmNDaGFyU2V0RXF1YWwgKG0udS5jLCB2LnUuYyk7CgkJYnJlYWs7CgkgICAgY2FzZSBGY09wTm90RXF1YWw6CgkJcmV0ID0gIUZjQ2hhclNldEVxdWFsIChtLnUuYywgdi51LmMpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVWb2lkOgoJICAgIHN3aXRjaCAob3ApIHsKCSAgICBjYXNlIEZjT3BFcXVhbDoKCSAgICBjYXNlIEZjT3BDb250YWluczoKCQlyZXQgPSBGY1RydWU7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCSAgICB9CgkgICAgYnJlYWs7Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAob3AgPT0gRmNPcE5vdEVxdWFsKQoJICAgIHJldCA9IEZjVHJ1ZTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCgpzdGF0aWMgRmNWYWx1ZQpGY0NvbmZpZ0V2YWx1YXRlIChGY1BhdHRlcm4gKnAsIEZjRXhwciAqZSkKewogICAgRmNWYWx1ZQl2LCB2bCwgdnI7CiAgICBGY1Jlc3VsdAlyOwogICAgRmNNYXRyaXgJKm07CiAgICAKICAgIHN3aXRjaCAoZS0+b3ApIHsKICAgIGNhc2UgRmNPcEludGVnZXI6Cgl2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJdi51LmkgPSBlLT51Lml2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcERvdWJsZToKCXYudHlwZSA9IEZjVHlwZURvdWJsZTsKCXYudS5kID0gZS0+dS5kdmFsOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BTdHJpbmc6Cgl2LnR5cGUgPSBGY1R5cGVTdHJpbmc7Cgl2LnUucyA9IGUtPnUuc3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcE1hdHJpeDoKCXYudHlwZSA9IEZjVHlwZU1hdHJpeDsKCXYudS5tID0gZS0+dS5tdmFsOwoJdiA9IEZjVmFsdWVTYXZlICh2KTsKCWJyZWFrOwogICAgY2FzZSBGY09wQ2hhclNldDoKCXYudHlwZSA9IEZjVHlwZUNoYXJTZXQ7Cgl2LnUuYyA9IGUtPnUuY3ZhbDsKCXYgPSBGY1ZhbHVlU2F2ZSAodik7CglicmVhazsKICAgIGNhc2UgRmNPcEJvb2w6Cgl2LnR5cGUgPSBGY1R5cGVCb29sOwoJdi51LmIgPSBlLT51LmJ2YWw7CglicmVhazsKICAgIGNhc2UgRmNPcEZpZWxkOgoJciA9IEZjUGF0dGVybkdldCAocCwgZS0+dS5maWVsZCwgMCwgJnYpOwoJaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BDb25zdDoKCWlmIChGY05hbWVDb25zdGFudCAoZS0+dS5jb25zdGFudCwgJnYudS5pKSkKCSAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNPcFF1ZXN0OgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7CglpZiAodmwudHlwZSA9PSBGY1R5cGVCb29sKQoJewoJICAgIGlmICh2bC51LmIpCgkJdiA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5yaWdodC0+dS50cmVlLmxlZnQpOwoJICAgIGVsc2UKCQl2ID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0LT51LnRyZWUucmlnaHQpOwoJfQoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJYnJlYWs7CiAgICBjYXNlIEZjT3BPcjoKICAgIGNhc2UgRmNPcEFuZDoKICAgIGNhc2UgRmNPcEVxdWFsOgogICAgY2FzZSBGY09wQ29udGFpbnM6CiAgICBjYXNlIEZjT3BOb3RFcXVhbDoKICAgIGNhc2UgRmNPcExlc3M6CiAgICBjYXNlIEZjT3BMZXNzRXF1YWw6CiAgICBjYXNlIEZjT3BNb3JlOgogICAgY2FzZSBGY09wTW9yZUVxdWFsOgogICAgY2FzZSBGY09wUGx1czoKICAgIGNhc2UgRmNPcE1pbnVzOgogICAgY2FzZSBGY09wVGltZXM6CiAgICBjYXNlIEZjT3BEaXZpZGU6Cgl2bCA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIGUtPnUudHJlZS5sZWZ0KTsKCXZyID0gRmNDb25maWdFdmFsdWF0ZSAocCwgZS0+dS50cmVlLnJpZ2h0KTsKCXZsID0gRmNDb25maWdQcm9tb3RlICh2bCwgdnIpOwoJdnIgPSBGY0NvbmZpZ1Byb21vdGUgKHZyLCB2bCk7CglpZiAodmwudHlwZSA9PSB2ci50eXBlKQoJewoJICAgIHN3aXRjaCAodmwudHlwZSkgewoJICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BQbHVzOgkgICAKCQkgICAgdi50eXBlID0gRmNUeXBlRG91YmxlOwoJCSAgICB2LnUuZCA9IHZsLnUuZCArIHZyLnUuZDsgCgkJICAgIGJyZWFrOwoJCWNhc2UgRmNPcE1pbnVzOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CgkJICAgIHYudS5kID0gdmwudS5kIC0gdnIudS5kOyAKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wVGltZXM6CgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgKiB2ci51LmQ7IAoJCSAgICBicmVhazsKCQljYXNlIEZjT3BEaXZpZGU6CgkJICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKCQkgICAgdi51LmQgPSB2bC51LmQgLyB2ci51LmQ7IAoJCSAgICBicmVhazsKCQljYXNlIEZjT3BFcXVhbDoKCQljYXNlIEZjT3BDb250YWluczoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsgCgkJICAgIHYudS5iID0gdmwudS5kID09IHZyLnUuZDsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6ICAgIAoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOyAKCQkgICAgdi51LmIgPSB2bC51LmQgIT0gdnIudS5kOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BMZXNzOiAgICAKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsgCgkJICAgIHYudS5iID0gdmwudS5kIDwgdnIudS5kOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BMZXNzRXF1YWw6ICAgIAoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOyAKCQkgICAgdi51LmIgPSB2bC51LmQgPD0gdnIudS5kOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BNb3JlOiAgICAKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsgCgkJICAgIHYudS5iID0gdmwudS5kID4gdnIudS5kOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BNb3JlRXF1YWw6ICAgIAoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOyAKCQkgICAgdi51LmIgPSB2bC51LmQgPj0gdnIudS5kOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOyAKCQkgICAgYnJlYWs7CgkJfQoJCWlmICh2LnR5cGUgPT0gRmNUeXBlRG91YmxlICYmCgkJICAgIHYudS5kID09IChkb3VibGUpIChpbnQpIHYudS5kKQoJCXsKCQkgICAgdi50eXBlID0gRmNUeXBlSW50ZWdlcjsKCQkgICAgdi51LmkgPSAoaW50KSB2LnUuZDsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBGY1R5cGVCb29sOgoJCXN3aXRjaCAoZS0+b3ApIHsKCQljYXNlIEZjT3BPcjoKCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSB2bC51LmIgfHwgdnIudS5iOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BBbmQ6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gdmwudS5iICYmIHZyLnUuYjsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wRXF1YWw6CgkJY2FzZSBGY09wQ29udGFpbnM6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gdmwudS5iID09IHZyLnUuYjsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gdmwudS5iICE9IHZyLnUuYjsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsgCgkJICAgIGJyZWFrOwoJCX0KCQlicmVhazsKCSAgICBjYXNlIEZjVHlwZVN0cmluZzoKCQlzd2l0Y2ggKGUtPm9wKSB7CgkJY2FzZSBGY09wRXF1YWw6CgkJY2FzZSBGY09wQ29udGFpbnM6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNTdHJDbXBJZ25vcmVDYXNlICh2bC51LnMsIHZyLnUucykgPT0gMDsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNTdHJDbXBJZ25vcmVDYXNlICh2bC51LnMsIHZyLnUucykgIT0gMDsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wUGx1czoKCQkgICAgdi50eXBlID0gRmNUeXBlU3RyaW5nOwoJCSAgICB2LnUucyA9IEZjU3RyUGx1cyAodmwudS5zLCB2ci51LnMpOwoJCSAgICBpZiAoIXYudS5zKQoJCQl2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB2LnR5cGUgPSBGY1R5cGVWb2lkOwoJCSAgICBicmVhazsKCQl9CgkgICAgY2FzZSBGY1R5cGVNYXRyaXg6CgkJc3dpdGNoIChlLT5vcCkgewoJCWNhc2UgRmNPcEVxdWFsOgoJCWNhc2UgRmNPcENvbnRhaW5zOgoJCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwoJCSAgICB2LnUuYiA9IEZjTWF0cml4RXF1YWwgKHZsLnUubSwgdnIudS5tKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNNYXRyaXhFcXVhbCAodmwudS5tLCB2ci51Lm0pOwoJCSAgICBicmVhazsKCQljYXNlIEZjT3BUaW1lczoKCQkgICAgdi50eXBlID0gRmNUeXBlTWF0cml4OwoJCSAgICBtID0gbWFsbG9jIChzaXplb2YgKEZjTWF0cml4KSk7CgkJICAgIGlmIChtKQoJCSAgICB7CgkJCUZjTWVtQWxsb2MgKEZDX01FTV9NQVRSSVgsIHNpemVvZiAoRmNNYXRyaXgpKTsKCQkJRmNNYXRyaXhNdWx0aXBseSAobSwgdmwudS5tLCB2ci51Lm0pOwoJCQl2LnUubSA9IG07CgkJICAgIH0KCQkgICAgZWxzZQoJCSAgICB7CgkJCXYudHlwZSA9IEZjVHlwZVZvaWQ7CgkJICAgIH0KCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCQkgICAgYnJlYWs7CgkJfQoJCWJyZWFrOwoJICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCQlzd2l0Y2ggKGUtPm9wKSB7CgkJY2FzZSBGY09wQ29udGFpbnM6CgkJICAgIC8qIHZsIGNvbnRhaW5zIHZyIGlmIHZyIC0gdmwgaXMgZW1wdHkgKi8KCQkgICAgdi50eXBlID0gRmNUeXBlQm9vbDsKCQkgICAgdi51LmIgPSBGY0NoYXJTZXRTdWJ0cmFjdENvdW50ICh2ci51LmMsIHZsLnUuYykgPT0gMDsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wRXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gRmNDaGFyU2V0RXF1YWwgKHZsLnUuYywgdnIudS5jKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBGY09wTm90RXF1YWw6CgkJICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CgkJICAgIHYudS5iID0gIUZjQ2hhclNldEVxdWFsICh2bC51LmMsIHZyLnUuYyk7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CgkJICAgIGJyZWFrOwoJCX0KCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCXYudHlwZSA9IEZjVHlwZVZvaWQ7CgkJYnJlYWs7CgkgICAgfQoJfQoJZWxzZQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglGY1ZhbHVlRGVzdHJveSAodmwpOwoJRmNWYWx1ZURlc3Ryb3kgKHZyKTsKCWJyZWFrOwogICAgY2FzZSBGY09wTm90OgoJdmwgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7Cglzd2l0Y2ggKHZsLnR5cGUpIHsKCWNhc2UgRmNUeXBlQm9vbDoKCSAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwoJICAgIHYudS5iID0gIXZsLnUuYjsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCSAgICBicmVhazsKCX0KCUZjVmFsdWVEZXN0cm95ICh2bCk7CglicmVhazsKICAgIGRlZmF1bHQ6Cgl2LnR5cGUgPSBGY1R5cGVWb2lkOwoJYnJlYWs7CiAgICB9CiAgICByZXR1cm4gdjsKfQoKc3RhdGljIEZjVmFsdWVMaXN0ICoKRmNDb25maWdNYXRjaFZhbHVlTGlzdCAoRmNQYXR0ZXJuCSpwLAoJCQlGY1Rlc3QJCSp0LAoJCQlGY1ZhbHVlTGlzdAkqdikKewogICAgRmNWYWx1ZUxpc3QgICAgKnJldCA9IDA7CiAgICBGY1ZhbHVlCSAgICB2YWx1ZSA9IEZjQ29uZmlnRXZhbHVhdGUgKHAsIHQtPmV4cHIpOwogICAgCiAgICBmb3IgKDsgdjsgdiA9IHYtPm5leHQpCiAgICB7CglpZiAoRmNDb25maWdDb21wYXJlVmFsdWUgKHYtPnZhbHVlLCB0LT5vcCwgdmFsdWUpKQoJewoJICAgIGlmICghcmV0KQoJCXJldCA9IHY7Cgl9CgllbHNlCgl7CgkgICAgaWYgKHQtPnF1YWwgPT0gRmNRdWFsQWxsKQoJICAgIHsKCQlyZXQgPSAwOwoJCWJyZWFrOwoJICAgIH0KCX0KICAgIH0KICAgIEZjVmFsdWVEZXN0cm95ICh2YWx1ZSk7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgRmNWYWx1ZUxpc3QgKgpGY0NvbmZpZ1ZhbHVlcyAoRmNQYXR0ZXJuICpwLCBGY0V4cHIgKmUpCnsKICAgIEZjVmFsdWVMaXN0CSpsOwogICAgCiAgICBpZiAoIWUpCglyZXR1cm4gMDsKICAgIGwgPSAoRmNWYWx1ZUxpc3QgKikgbWFsbG9jIChzaXplb2YgKEZjVmFsdWVMaXN0KSk7CiAgICBpZiAoIWwpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9WQUxMSVNULCBzaXplb2YgKEZjVmFsdWVMaXN0KSk7CiAgICBpZiAoZS0+b3AgPT0gRmNPcENvbW1hKQogICAgewoJbC0+dmFsdWUgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlLT51LnRyZWUubGVmdCk7CglsLT5uZXh0ICA9IEZjQ29uZmlnVmFsdWVzIChwLCBlLT51LnRyZWUucmlnaHQpOwogICAgfQogICAgZWxzZQogICAgewoJbC0+dmFsdWUgPSBGY0NvbmZpZ0V2YWx1YXRlIChwLCBlKTsKCWwtPm5leHQgID0gMDsKICAgIH0KICAgIHdoaWxlIChsLT52YWx1ZS50eXBlID09IEZjVHlwZVZvaWQpCiAgICB7CglGY1ZhbHVlTGlzdAkqbmV4dCA9IGwtPm5leHQ7CgkKCUZjTWVtRnJlZSAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKCWZyZWUgKGwpOwoJbCA9IG5leHQ7CiAgICB9CiAgICByZXR1cm4gbDsKfQoKc3RhdGljIEZjQm9vbApGY0NvbmZpZ0FkZCAoRmNWYWx1ZUxpc3QgICAgKipoZWFkLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqcG9zaXRpb24sCgkgICAgIEZjQm9vbAkgICAgYXBwZW5kLAoJICAgICBGY1ZhbHVlTGlzdCAgICAqbmV3KQp7CiAgICBGY1ZhbHVlTGlzdCAgICAqKnByZXYsICpsYXN0OwogICAgCiAgICBpZiAoYXBwZW5kKQogICAgewoJaWYgKHBvc2l0aW9uKQoJICAgIHByZXYgPSAmcG9zaXRpb24tPm5leHQ7CgllbHNlCgkgICAgZm9yIChwcmV2ID0gaGVhZDsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKCQk7CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAocG9zaXRpb24pCgl7CgkgICAgZm9yIChwcmV2ID0gaGVhZDsgKnByZXY7IHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKCSAgICB7CgkJaWYgKCpwcmV2ID09IHBvc2l0aW9uKQoJCSAgICBicmVhazsKCSAgICB9Cgl9CgllbHNlCgkgICAgcHJldiA9IGhlYWQ7CgoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCXsKCSAgICBpZiAoISpwcmV2KQoJCXByaW50ZiAoInBvc2l0aW9uIG5vdCBvbiBsaXN0XG4iKTsKCX0KICAgIH0KCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiJXMgbGlzdCBiZWZvcmUgIiwgYXBwZW5kID8gIkFwcGVuZCIgOiAiUHJlcGVuZCIpOwoJRmNWYWx1ZUxpc3RQcmludCAoKmhlYWQpOwoJcHJpbnRmICgiXG4iKTsKICAgIH0KICAgIAogICAgaWYgKG5ldykKICAgIHsKCWxhc3QgPSBuZXc7Cgl3aGlsZSAobGFzdC0+bmV4dCkKCSAgICBsYXN0ID0gbGFzdC0+bmV4dDsKICAgIAoJbGFzdC0+bmV4dCA9ICpwcmV2OwoJKnByZXYgPSBuZXc7CiAgICB9CiAgICAKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCiAgICB7CglwcmludGYgKCIlcyBsaXN0IGFmdGVyICIsIGFwcGVuZCA/ICJBcHBlbmQiIDogIlByZXBlbmQiKTsKCUZjVmFsdWVMaXN0UHJpbnQgKCpoZWFkKTsKCXByaW50ZiAoIlxuIik7CiAgICB9CiAgICAKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnRGVsIChGY1ZhbHVlTGlzdCAgICAqKmhlYWQsCgkgICAgIEZjVmFsdWVMaXN0ICAgICpwb3NpdGlvbikKewogICAgRmNWYWx1ZUxpc3QgICAgKipwcmV2OwoKICAgIGZvciAocHJldiA9IGhlYWQ7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpCiAgICB7CglpZiAoKnByZXYgPT0gcG9zaXRpb24pCgl7CgkgICAgKnByZXYgPSBwb3NpdGlvbi0+bmV4dDsKCSAgICBwb3NpdGlvbi0+bmV4dCA9IDA7CgkgICAgRmNWYWx1ZUxpc3REZXN0cm95IChwb3NpdGlvbik7CgkgICAgYnJlYWs7Cgl9CiAgICB9Cn0KCnN0YXRpYyB2b2lkCkZjQ29uZmlnUGF0dGVybkFkZCAoRmNQYXR0ZXJuCSpwLAoJCSAgICBjb25zdCBjaGFyCSpvYmplY3QsCgkJICAgIEZjVmFsdWVMaXN0CSpsaXN0LAoJCSAgICBGY0Jvb2wJYXBwZW5kKQp7CiAgICBpZiAobGlzdCkKICAgIHsKCUZjUGF0dGVybkVsdCAgICAqZSA9IEZjUGF0dGVybkZpbmQgKHAsIG9iamVjdCwgRmNUcnVlKTsKICAgIAoJaWYgKCFlKQoJICAgIHJldHVybjsKCUZjQ29uZmlnQWRkICgmZS0+dmFsdWVzLCAwLCBhcHBlbmQsIGxpc3QpOwogICAgfQp9CgovKgogKiBEZWxldGUgYWxsIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGggYSBmaWVsZAogKi8Kc3RhdGljIHZvaWQKRmNDb25maWdQYXR0ZXJuRGVsIChGY1BhdHRlcm4JKnAsCgkJICAgIGNvbnN0IGNoYXIJKm9iamVjdCkKewogICAgRmNQYXR0ZXJuRWx0ICAgICplID0gRmNQYXR0ZXJuRmluZCAocCwgb2JqZWN0LCBGY0ZhbHNlKTsKICAgIGlmICghZSkKCXJldHVybjsKICAgIHdoaWxlIChlLT52YWx1ZXMpCglGY0NvbmZpZ0RlbCAoJmUtPnZhbHVlcywgZS0+dmFsdWVzKTsKfQoKc3RhdGljIHZvaWQKRmNDb25maWdQYXR0ZXJuQ2Fub24gKEZjUGF0dGVybgkgICAgKnAsCgkJICAgICAgY29uc3QgY2hhciAgICAqb2JqZWN0KQp7CiAgICBGY1BhdHRlcm5FbHQgICAgKmUgPSBGY1BhdHRlcm5GaW5kIChwLCBvYmplY3QsIEZjRmFsc2UpOwogICAgaWYgKCFlKQoJcmV0dXJuOwogICAgaWYgKCFlLT52YWx1ZXMpCglGY1BhdHRlcm5EZWwgKHAsIG9iamVjdCk7Cn0KCkZjQm9vbApGY0NvbmZpZ1N1YnN0aXR1dGUgKEZjQ29uZmlnCSpjb25maWcsCgkJICAgIEZjUGF0dGVybgkqcCwKCQkgICAgRmNNYXRjaEtpbmQJa2luZCkKewogICAgRmNTdWJzdAkgICAgKnM7CiAgICBGY1N1YlN0YXRlCSAgICAqc3Q7CiAgICBpbnQJCSAgICBpOwogICAgRmNUZXN0CSAgICAqdDsKICAgIEZjRWRpdAkgICAgKmU7CiAgICBGY1ZhbHVlTGlzdAkgICAgKmw7CgogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KCiAgICBzdCA9IChGY1N1YlN0YXRlICopIG1hbGxvYyAoY29uZmlnLT5tYXhPYmplY3RzICogc2l6ZW9mIChGY1N1YlN0YXRlKSk7CiAgICBpZiAoIXN0ICYmIGNvbmZpZy0+bWF4T2JqZWN0cykKCXJldHVybiBGY0ZhbHNlOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1NVQlNUQVRFLCBjb25maWctPm1heE9iamVjdHMgKiBzaXplb2YgKEZjU3ViU3RhdGUpKTsKCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQogICAgewoJcHJpbnRmICgiRmNDb25maWdTdWJzdGl0dXRlICIpOwoJRmNQYXR0ZXJuUHJpbnQgKHApOwogICAgfQogICAgaWYgKGtpbmQgPT0gRmNNYXRjaFBhdHRlcm4pCglzID0gY29uZmlnLT5zdWJzdFBhdHRlcm47CiAgICBlbHNlCglzID0gY29uZmlnLT5zdWJzdEZvbnQ7CiAgICBmb3IgKDsgczsgcyA9IHMtPm5leHQpCiAgICB7CgkvKgoJICogQ2hlY2sgdGhlIHRlc3RzIHRvIHNlZSBpZgoJICogdGhleSBhbGwgbWF0Y2ggdGhlIHBhdHRlcm4KCSAqLwoJZm9yICh0ID0gcy0+dGVzdCwgaSA9IDA7IHQ7IHQgPSB0LT5uZXh0LCBpKyspCgl7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKCSAgICB7CgkJcHJpbnRmICgiRmNDb25maWdTdWJzdGl0dXRlIHRlc3QgIik7CgkJRmNUZXN0UHJpbnQgKHQpOwoJICAgIH0KCSAgICBzdFtpXS5lbHQgPSBGY1BhdHRlcm5GaW5kIChwLCB0LT5maWVsZCwgRmNGYWxzZSk7CgkgICAgLyoKCSAgICAgKiBJZiB0aGVyZSdzIG5vIHN1Y2ggZmllbGQgaW4gdGhlIGZvbnQsCgkgICAgICogdGhlbiBGY1F1YWxBbGwgbWF0Y2hlcyB3aGlsZSBGY1F1YWxBbnkgZG9lcyBub3QKCSAgICAgKi8KCSAgICBpZiAoIXN0W2ldLmVsdCkKCSAgICB7CgkJaWYgKHQtPnF1YWwgPT0gRmNRdWFsQWxsKQoJCXsKCQkgICAgc3RbaV0udmFsdWUgPSAwOwoJCSAgICBjb250aW51ZTsKCQl9CgkJZWxzZQoJCSAgICBicmVhazsKCSAgICB9CgkgICAgLyoKCSAgICAgKiBDaGVjayB0byBzZWUgaWYgdGhlcmUgaXMgYSBtYXRjaCwgbWFyayB0aGUgbG9jYXRpb24KCSAgICAgKiB0byBhcHBseSBtYXRjaC1yZWxhdGl2ZSBlZGl0cwoJICAgICAqLwoJICAgIHN0W2ldLnZhbHVlID0gRmNDb25maWdNYXRjaFZhbHVlTGlzdCAocCwgdCwgc3RbaV0uZWx0LT52YWx1ZXMpOwoJICAgIGlmICghc3RbaV0udmFsdWUpCgkJYnJlYWs7Cgl9CglpZiAodCkKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJCXByaW50ZiAoIk5vIG1hdGNoXG4iKTsKCSAgICBjb250aW51ZTsKCX0KCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0VESVQpCgl7CgkgICAgcHJpbnRmICgiU3Vic3RpdHV0ZSAiKTsKCSAgICBGY1N1YnN0UHJpbnQgKHMpOwoJfQoJZm9yIChlID0gcy0+ZWRpdDsgZTsgZSA9IGUtPm5leHQpCgl7CgkgICAgLyoKCSAgICAgKiBFdmFsdWF0ZSB0aGUgbGlzdCBvZiBleHByZXNzaW9ucwoJICAgICAqLwoJICAgIGwgPSBGY0NvbmZpZ1ZhbHVlcyAocCwgZS0+ZXhwcik7CgkgICAgLyoKCSAgICAgKiBMb2NhdGUgYW55IHRlc3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZmllbGQKCSAgICAgKi8KCSAgICBmb3IgKHQgPSBzLT50ZXN0LCBpID0gMDsgdDsgdCA9IHQtPm5leHQsIGkrKykKCQlpZiAoIUZjU3RyQ21wSWdub3JlQ2FzZSAoKEZjQ2hhcjggKikgdC0+ZmllbGQsIChGY0NoYXI4ICopIGUtPmZpZWxkKSkKCQkgICAgYnJlYWs7CgkgICAgc3dpdGNoIChlLT5vcCkgewoJICAgIGNhc2UgRmNPcEFzc2lnbjoKCQkvKgoJCSAqIElmIHRoZXJlIHdhcyBhIHRlc3QsIHRoZW4gcmVwbGFjZSB0aGUgbWF0Y2hlZAoJCSAqIHZhbHVlIHdpdGggdGhlIG5ldyBsaXN0IG9mIHZhbHVlcwoJCSAqLwoJCWlmICh0KQoJCXsKCQkgICAgRmNWYWx1ZUxpc3QJKnRoaXNWYWx1ZSA9IHN0W2ldLnZhbHVlOwoJCSAgICBGY1ZhbHVlTGlzdAkqbmV4dFZhbHVlID0gdGhpc1ZhbHVlID8gdGhpc1ZhbHVlLT5uZXh0IDogMDsKCQkgICAgCgkJICAgIC8qCgkJICAgICAqIEFwcGVuZCB0aGUgbmV3IGxpc3Qgb2YgdmFsdWVzIGFmdGVyIHRoZSBjdXJyZW50IHZhbHVlCgkJICAgICAqLwoJCSAgICBGY0NvbmZpZ0FkZCAoJnN0W2ldLmVsdC0+dmFsdWVzLCB0aGlzVmFsdWUsIEZjVHJ1ZSwgbCk7CgkJICAgIC8qCgkJICAgICAqIERlbGV0ZSB0aGUgbWFya2VkIHZhbHVlCgkJICAgICAqLwoJCSAgICBGY0NvbmZpZ0RlbCAoJnN0W2ldLmVsdC0+dmFsdWVzLCB0aGlzVmFsdWUpOwoJCSAgICAvKgoJCSAgICAgKiBBZGp1c3QgYW55IHBvaW50ZXJzIGludG8gdGhlIHZhbHVlIGxpc3QgdG8gZW5zdXJlCgkJICAgICAqIGZ1dHVyZSBlZGl0cyBvY2N1ciBhdCB0aGUgc2FtZSBwbGFjZQoJCSAgICAgKi8KCQkgICAgZm9yICh0ID0gcy0+dGVzdCwgaSA9IDA7IHQ7IHQgPSB0LT5uZXh0LCBpKyspCgkJICAgIHsKCQkJaWYgKHN0W2ldLnZhbHVlID09IHRoaXNWYWx1ZSkKCQkJICAgIHN0W2ldLnZhbHVlID0gbmV4dFZhbHVlOwoJCSAgICB9CgkJICAgIGJyZWFrOwoJCX0KCQkvKiBmYWxsIHRocm91Z2ggLi4uICovCgkgICAgY2FzZSBGY09wQXNzaWduUmVwbGFjZToKCQkvKgoJCSAqIERlbGV0ZSBhbGwgb2YgdGhlIHZhbHVlcyBhbmQgaW5zZXJ0CgkJICogdGhlIG5ldyBzZXQKCQkgKi8KCQlGY0NvbmZpZ1BhdHRlcm5EZWwgKHAsIGUtPmZpZWxkKTsKCQlGY0NvbmZpZ1BhdHRlcm5BZGQgKHAsIGUtPmZpZWxkLCBsLCBGY1RydWUpOwoJCS8qCgkJICogQWRqdXN0IGFueSBwb2ludGVycyBpbnRvIHRoZSB2YWx1ZSBsaXN0IGFzIHRoZXkgbm8KCQkgKiBsb25nZXIgcG9pbnQgdG8gYW55dGhpbmcgdmFsaWQKCQkgKi8KCQlpZiAodCkKCQl7CgkJICAgIEZjUGF0dGVybkVsdCAgICAqdGhpc0VsdCA9IHN0W2ldLmVsdDsKCQkgICAgZm9yICh0ID0gcy0+dGVzdCwgaSA9IDA7IHQ7IHQgPSB0LT5uZXh0LCBpKyspCgkJICAgIHsKCQkJaWYgKHN0W2ldLmVsdCA9PSB0aGlzRWx0KQoJCQkgICAgc3RbaV0udmFsdWUgPSAwOwoJCSAgICB9CgkJfQoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcFByZXBlbmQ6CgkJaWYgKHQpCgkJewoJCSAgICBGY0NvbmZpZ0FkZCAoJnN0W2ldLmVsdC0+dmFsdWVzLCBzdFtpXS52YWx1ZSwgRmNGYWxzZSwgbCk7CgkJICAgIGJyZWFrOwoJCX0KCQkvKiBmYWxsIHRocm91Z2ggLi4uICovCgkgICAgY2FzZSBGY09wUHJlcGVuZEZpcnN0OgoJCUZjQ29uZmlnUGF0dGVybkFkZCAocCwgZS0+ZmllbGQsIGwsIEZjRmFsc2UpOwoJCWJyZWFrOwoJICAgIGNhc2UgRmNPcEFwcGVuZDoKCQlpZiAodCkKCQl7CgkJICAgIEZjQ29uZmlnQWRkICgmc3RbaV0uZWx0LT52YWx1ZXMsIHN0W2ldLnZhbHVlLCBGY1RydWUsIGwpOwoJCSAgICBicmVhazsKCQl9CgkJLyogZmFsbCB0aHJvdWdoIC4uLiAqLwoJICAgIGNhc2UgRmNPcEFwcGVuZExhc3Q6CgkJRmNDb25maWdQYXR0ZXJuQWRkIChwLCBlLT5maWVsZCwgbCwgRmNUcnVlKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJICAgIH0KCX0KCS8qCgkgKiBOb3cgZ28gdGhyb3VnaCB0aGUgcGF0dGVybiBhbmQgZWxpbWluYXRlCgkgKiBhbnkgcHJvcGVydGllcyB3aXRob3V0IGRhdGEKCSAqLwoJZm9yIChlID0gcy0+ZWRpdDsgZTsgZSA9IGUtPm5leHQpCgkgICAgRmNDb25maWdQYXR0ZXJuQ2Fub24gKHAsIGUtPmZpZWxkKTsKCglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19FRElUKQoJewoJICAgIHByaW50ZiAoIkZjQ29uZmlnU3Vic3RpdHV0ZSBlZGl0Iik7CgkgICAgRmNQYXR0ZXJuUHJpbnQgKHApOwoJfQogICAgfQogICAgRmNNZW1GcmVlIChGQ19NRU1fU1VCU1RBVEUsIGNvbmZpZy0+bWF4T2JqZWN0cyAqIHNpemVvZiAoRmNTdWJTdGF0ZSkpOwogICAgZnJlZSAoc3QpOwogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfRURJVCkKICAgIHsKCXByaW50ZiAoIkZjQ29uZmlnU3Vic3RpdHV0ZSBkb25lIik7CglGY1BhdHRlcm5QcmludCAocCk7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgojaWZuZGVmIEZPTlRDT05GSUdfUEFUSAojZGVmaW5lIEZPTlRDT05GSUdfUEFUSAkiL2V0Yy9mb250cyIKI2VuZGlmCgojaWZuZGVmIEZPTlRDT05GSUdfRklMRQojZGVmaW5lIEZPTlRDT05GSUdfRklMRQkiZm9udHMuY29uZiIKI2VuZGlmCgpzdGF0aWMgRmNDaGFyOCAqCkZjQ29uZmlnRmlsZUV4aXN0cyAoY29uc3QgRmNDaGFyOCAqZGlyLCBjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBGY0NoYXI4ICAgICpwYXRoOwoKICAgIGlmICghZGlyKQoJZGlyID0gKEZjQ2hhcjggKikgIiI7CiAgICBwYXRoID0gbWFsbG9jIChzdHJsZW4gKChjaGFyICopIGRpcikgKyAxICsgc3RybGVuICgoY2hhciAqKSBmaWxlKSArIDEpOwogICAgaWYgKCFwYXRoKQoJcmV0dXJuIDA7CgogICAgc3RyY3B5IChwYXRoLCBkaXIpOwogICAgLyogbWFrZSBzdXJlIHRoZXJlJ3MgYSBzaW5nbGUgc2VwYXJhdGluZyAvICovCiAgICBpZiAoKCFwYXRoWzBdIHx8IHBhdGhbc3RybGVuKChjaGFyICopIHBhdGgpLTFdICE9ICcvJykgJiYgZmlsZVswXSAhPSAnLycpCglzdHJjYXQgKChjaGFyICopIHBhdGgsICIvIik7CiAgICBzdHJjYXQgKChjaGFyICopIHBhdGgsIChjaGFyICopIGZpbGUpOwoKICAgIGlmIChhY2Nlc3MgKChjaGFyICopIHBhdGgsIFJfT0spID09IDApCglyZXR1cm4gcGF0aDsKICAgIAogICAgZnJlZSAocGF0aCk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZjQ2hhcjggKioKRmNDb25maWdHZXRQYXRoICh2b2lkKQp7CiAgICBGY0NoYXI4ICAgICoqcGF0aDsKICAgIEZjQ2hhcjggICAgKmVudiwgKmUsICpjb2xvbjsKICAgIEZjQ2hhcjggICAgKmRpcjsKICAgIGludAkgICAgbnBhdGg7CiAgICBpbnQJICAgIGk7CgogICAgbnBhdGggPSAyOwkvKiBkZWZhdWx0IGRpciArIG51bGwgKi8KICAgIGVudiA9IChGY0NoYXI4ICopIGdldGVudiAoIkZPTlRDT05GSUdfUEFUSCIpOwogICAgaWYgKGVudikKICAgIHsKCWUgPSBlbnY7CglucGF0aCsrOwoJd2hpbGUgKCplKQoJICAgIGlmICgqZSsrID09ICc6JykKCQlucGF0aCsrOwogICAgfQogICAgcGF0aCA9IGNhbGxvYyAobnBhdGgsIHNpemVvZiAoRmNDaGFyOCAqKSk7CiAgICBpZiAoIXBhdGgpCglnb3RvIGJhaWwwOwogICAgaSA9IDA7CgogICAgaWYgKGVudikKICAgIHsKCWUgPSBlbnY7Cgl3aGlsZSAoKmUpIAoJewoJICAgIGNvbG9uID0gKEZjQ2hhcjggKikgc3RyY2hyICgoY2hhciAqKSBlLCAnOicpOwoJICAgIGlmICghY29sb24pCgkJY29sb24gPSBlICsgc3RybGVuICgoY2hhciAqKSBlKTsKCSAgICBwYXRoW2ldID0gbWFsbG9jIChjb2xvbiAtIGUgKyAxKTsKCSAgICBpZiAoIXBhdGhbaV0pCgkJZ290byBiYWlsMTsKCSAgICBzdHJuY3B5IChwYXRoW2ldLCBlLCBjb2xvbiAtIGUpOwoJICAgIHBhdGhbaV1bY29sb24gLSBlXSA9ICdcMCc7CgkgICAgaWYgKCpjb2xvbikKCQllID0gY29sb24gKyAxOwoJICAgIGVsc2UKCQllID0gY29sb247CgkgICAgaSsrOwoJfQogICAgfQogICAgCiAgICBkaXIgPSAoRmNDaGFyOCAqKSBGT05UQ09ORklHX1BBVEg7CiAgICBwYXRoW2ldID0gbWFsbG9jIChzdHJsZW4gKChjaGFyICopIGRpcikgKyAxKTsKICAgIGlmICghcGF0aFtpXSkKCWdvdG8gYmFpbDE7CiAgICBzdHJjcHkgKHBhdGhbaV0sIGRpcik7CiAgICByZXR1cm4gcGF0aDsKCmJhaWwxOgogICAgZm9yIChpID0gMDsgcGF0aFtpXTsgaSsrKQoJZnJlZSAocGF0aFtpXSk7CiAgICBmcmVlIChwYXRoKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKRmNDb25maWdGcmVlUGF0aCAoRmNDaGFyOCAqKnBhdGgpCnsKICAgIEZjQ2hhcjggICAgKipwOwoKICAgIGZvciAocCA9IHBhdGg7ICpwOyBwKyspCglmcmVlICgqcCk7CiAgICBmcmVlIChwYXRoKTsKfQoKRmNDaGFyOCAqCkZjQ29uZmlnRmlsZW5hbWUgKGNvbnN0IEZjQ2hhcjggKnVybCkKewogICAgRmNDaGFyOCAgICAqZmlsZSwgKmRpciwgKipwYXRoLCAqKnA7CiAgICAKICAgIGlmICghdXJsIHx8ICEqdXJsKQogICAgewoJdXJsID0gKEZjQ2hhcjggKikgZ2V0ZW52ICgiRk9OVENPTkZJR19GSUxFIik7CglpZiAoIXVybCkKCSAgICB1cmwgPSAoRmNDaGFyOCAqKSBGT05UQ09ORklHX0ZJTEU7CiAgICB9CiAgICBmaWxlID0gMDsKICAgIHN3aXRjaCAoKnVybCkgewogICAgY2FzZSAnfic6CglkaXIgPSAoRmNDaGFyOCAqKSBnZXRlbnYgKCJIT01FIik7CglpZiAoZGlyKQoJICAgIGZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKGRpciwgdXJsICsgMSk7CgllbHNlCgkgICAgZmlsZSA9IDA7CglicmVhazsKICAgIGNhc2UgJy8nOgoJZmlsZSA9IEZjQ29uZmlnRmlsZUV4aXN0cyAoMCwgdXJsKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCXBhdGggPSBGY0NvbmZpZ0dldFBhdGggKCk7CglpZiAoIXBhdGgpCgkgICAgcmV0dXJuIDA7Cglmb3IgKHAgPSBwYXRoOyAqcDsgcCsrKQoJewoJICAgIGZpbGUgPSBGY0NvbmZpZ0ZpbGVFeGlzdHMgKCpwLCB1cmwpOwoJICAgIGlmIChmaWxlKQoJCWJyZWFrOwoJfQoJRmNDb25maWdGcmVlUGF0aCAocGF0aCk7CglicmVhazsKICAgIH0KICAgIHJldHVybiBmaWxlOwp9CgovKgogKiBNYW5hZ2UgdGhlIGFwcGxpY2F0aW9uLXNwZWNpZmljIGZvbnRzCiAqLwoKRmNCb29sCkZjQ29uZmlnQXBwRm9udEFkZEZpbGUgKEZjQ29uZmlnICAgICpjb25maWcsCgkJCWNvbnN0IEZjQ2hhcjggICpmaWxlKQp7CiAgICBGY0ZvbnRTZXQJKnNldDsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIHNldCA9IEZjQ29uZmlnR2V0Rm9udHMgKGNvbmZpZywgRmNTZXRBcHBsaWNhdGlvbik7CiAgICBpZiAoIXNldCkKICAgIHsKCXNldCA9IEZjRm9udFNldENyZWF0ZSAoKTsKCWlmICghc2V0KQoJICAgIHJldHVybiBGY0ZhbHNlOwoJRmNDb25maWdTZXRGb250cyAoY29uZmlnLCBzZXQsIEZjU2V0QXBwbGljYXRpb24pOwogICAgfQogICAgcmV0dXJuIEZjRmlsZVNjYW4gKHNldCwgMCwgY29uZmlnLT5ibGFua3MsIGZpbGUsIEZjRmFsc2UpOwp9CgpGY0Jvb2wKRmNDb25maWdBcHBGb250QWRkRGlyIChGY0NvbmZpZwkgICAgKmNvbmZpZywKCQkgICAgICAgY29uc3QgRmNDaGFyOCAgICpkaXIpCnsKICAgIEZjRm9udFNldAkqc2V0OwogICAgCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgc2V0ID0gRmNDb25maWdHZXRGb250cyAoY29uZmlnLCBGY1NldEFwcGxpY2F0aW9uKTsKICAgIGlmICghc2V0KQogICAgewoJc2V0ID0gRmNGb250U2V0Q3JlYXRlICgpOwoJaWYgKCFzZXQpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglGY0NvbmZpZ1NldEZvbnRzIChjb25maWcsIHNldCwgRmNTZXRBcHBsaWNhdGlvbik7CiAgICB9CiAgICByZXR1cm4gRmNEaXJTY2FuIChzZXQsIDAsIGNvbmZpZy0+YmxhbmtzLCBkaXIsIEZjRmFsc2UpOwp9Cgp2b2lkCkZjQ29uZmlnQXBwRm9udENsZWFyIChGY0NvbmZpZwkgICAgKmNvbmZpZykKewogICAgRmNDb25maWdTZXRGb250cyAoY29uZmlnLCAwLCBGY1NldEFwcGxpY2F0aW9uKTsKfQo=