LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNtYXRjaC5jLHYgMS4yMCAyMDAyLzA4LzMxIDIyOjE3OjMyIGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlICJmY2ludC5oIgojaW5jbHVkZSA8c3RkaW8uaD4KCnN0YXRpYyBkb3VibGUKRmNDb21wYXJlTnVtYmVyIChjaGFyICpvYmplY3QsIEZjVmFsdWUgdmFsdWUxLCBGY1ZhbHVlIHZhbHVlMikKewogICAgZG91YmxlICB2MSwgdjIsIHY7CiAgICAKICAgIHN3aXRjaCAodmFsdWUxLnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCXYxID0gKGRvdWJsZSkgdmFsdWUxLnUuaTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVEb3VibGU6Cgl2MSA9IHZhbHVlMS51LmQ7CglicmVhazsKICAgIGRlZmF1bHQ6CglyZXR1cm4gLTEuMDsKICAgIH0KICAgIHN3aXRjaCAodmFsdWUyLnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCXYyID0gKGRvdWJsZSkgdmFsdWUyLnUuaTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVEb3VibGU6Cgl2MiA9IHZhbHVlMi51LmQ7CglicmVhazsKICAgIGRlZmF1bHQ6CglyZXR1cm4gLTEuMDsKICAgIH0KICAgIHYgPSB2MiAtIHYxOwogICAgaWYgKHYgPCAwKQoJdiA9IC12OwogICAgcmV0dXJuIChkb3VibGUpIHY7Cn0KCnN0YXRpYyBkb3VibGUKRmNDb21wYXJlU3RyaW5nIChjaGFyICpvYmplY3QsIEZjVmFsdWUgdmFsdWUxLCBGY1ZhbHVlIHZhbHVlMikKewogICAgaWYgKHZhbHVlMi50eXBlICE9IEZjVHlwZVN0cmluZyB8fCB2YWx1ZTEudHlwZSAhPSBGY1R5cGVTdHJpbmcpCglyZXR1cm4gLTEuMDsKICAgIHJldHVybiAoZG91YmxlKSBGY1N0ckNtcElnbm9yZUNhc2UgKHZhbHVlMS51LnMsIHZhbHVlMi51LnMpICE9IDA7Cn0KCnN0YXRpYyBkb3VibGUKRmNDb21wYXJlRmFtaWx5IChjaGFyICpvYmplY3QsIEZjVmFsdWUgdmFsdWUxLCBGY1ZhbHVlIHZhbHVlMikKewogICAgaWYgKHZhbHVlMi50eXBlICE9IEZjVHlwZVN0cmluZyB8fCB2YWx1ZTEudHlwZSAhPSBGY1R5cGVTdHJpbmcpCglyZXR1cm4gLTEuMDsKICAgIHJldHVybiAoZG91YmxlKSBGY1N0ckNtcElnbm9yZUJsYW5rc0FuZENhc2UgKHZhbHVlMS51LnMsIHZhbHVlMi51LnMpICE9IDA7Cn0KCnN0YXRpYyBkb3VibGUKRmNDb21wYXJlTGFuZyAoY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlMSwgRmNWYWx1ZSB2YWx1ZTIpCnsKICAgIEZjTGFuZ1Jlc3VsdCAgICByZXN1bHQ7CiAgICAKICAgIHN3aXRjaCAodmFsdWUxLnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlTGFuZ1NldDoKCXN3aXRjaCAodmFsdWUyLnR5cGUpIHsKCWNhc2UgRmNUeXBlTGFuZ1NldDoKCSAgICByZXN1bHQgPSBGY0xhbmdTZXRDb21wYXJlICh2YWx1ZTEudS5sLCB2YWx1ZTIudS5sKTsKCSAgICBicmVhazsKCWNhc2UgRmNUeXBlU3RyaW5nOgoJICAgIHJlc3VsdCA9IEZjTGFuZ1NldEhhc0xhbmcgKHZhbHVlMS51LmwsIHZhbHVlMi51LnMpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gLTEuMDsKCX0KCWJyZWFrOwogICAgY2FzZSBGY1R5cGVTdHJpbmc6Cglzd2l0Y2ggKHZhbHVlMi50eXBlKSB7CgljYXNlIEZjVHlwZUxhbmdTZXQ6CgkgICAgcmVzdWx0ID0gRmNMYW5nU2V0SGFzTGFuZyAodmFsdWUyLnUubCwgdmFsdWUxLnUucyk7CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZVN0cmluZzoKCSAgICByZXN1bHQgPSBGY0xhbmdDb21wYXJlICh2YWx1ZTEudS5zLCB2YWx1ZTIudS5zKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIC0xLjA7Cgl9CglicmVhazsKICAgIGRlZmF1bHQ6CglyZXR1cm4gLTEuMDsKICAgIH0KICAgIHN3aXRjaCAocmVzdWx0KSB7CiAgICBjYXNlIEZjTGFuZ0VxdWFsOgoJcmV0dXJuIDA7CiAgICBjYXNlIEZjTGFuZ0RpZmZlcmVudENvdW50cnk6CglyZXR1cm4gMTsKICAgIGNhc2UgRmNMYW5nRGlmZmVyZW50TGFuZzoKICAgIGRlZmF1bHQ6CglyZXR1cm4gMjsKICAgIH0KfQoKc3RhdGljIGRvdWJsZQpGY0NvbXBhcmVCb29sIChjaGFyICpvYmplY3QsIEZjVmFsdWUgdmFsdWUxLCBGY1ZhbHVlIHZhbHVlMikKewogICAgaWYgKHZhbHVlMi50eXBlICE9IEZjVHlwZUJvb2wgfHwgdmFsdWUxLnR5cGUgIT0gRmNUeXBlQm9vbCkKCXJldHVybiAtMS4wOwogICAgcmV0dXJuIChkb3VibGUpIHZhbHVlMi51LmIgIT0gdmFsdWUxLnUuYjsKfQoKc3RhdGljIGRvdWJsZQpGY0NvbXBhcmVDaGFyU2V0IChjaGFyICpvYmplY3QsIEZjVmFsdWUgdmFsdWUxLCBGY1ZhbHVlIHZhbHVlMikKewogICAgaWYgKHZhbHVlMi50eXBlICE9IEZjVHlwZUNoYXJTZXQgfHwgdmFsdWUxLnR5cGUgIT0gRmNUeXBlQ2hhclNldCkKCXJldHVybiAtMS4wOwogICAgcmV0dXJuIChkb3VibGUpIEZjQ2hhclNldFN1YnRyYWN0Q291bnQgKHZhbHVlMS51LmMsIHZhbHVlMi51LmMpOwp9CgpzdGF0aWMgZG91YmxlCkZjQ29tcGFyZVNpemUgKGNoYXIgKm9iamVjdCwgRmNWYWx1ZSB2YWx1ZTEsIEZjVmFsdWUgdmFsdWUyKQp7CiAgICBkb3VibGUgIHYxLCB2MiwgdjsKCiAgICBzd2l0Y2ggKHZhbHVlMS50eXBlKSB7CiAgICBjYXNlIEZjVHlwZUludGVnZXI6Cgl2MSA9IHZhbHVlMS51Lmk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJdjEgPSB2YWx1ZTEudS5kOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJcmV0dXJuIC0xOwogICAgfQogICAgc3dpdGNoICh2YWx1ZTIudHlwZSkgewogICAgY2FzZSBGY1R5cGVJbnRlZ2VyOgoJdjIgPSB2YWx1ZTIudS5pOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCXYyID0gdmFsdWUyLnUuZDsKCWJyZWFrOwogICAgZGVmYXVsdDoKCXJldHVybiAtMTsKICAgIH0KICAgIGlmICh2MiA9PSAwKQoJcmV0dXJuIDA7CiAgICB2ID0gdjIgLSB2MTsKICAgIGlmICh2IDwgMCkKCXYgPSAtdjsKICAgIHJldHVybiB2Owp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNNYXRjaGVyIHsKICAgIGNoYXIJICAgICpvYmplY3Q7CiAgICBkb3VibGUJICAgICgqY29tcGFyZSkgKGNoYXIgKm9iamVjdCwgRmNWYWx1ZSB2YWx1ZTEsIEZjVmFsdWUgdmFsdWUyKTsKICAgIGludAkJICAgIHN0cm9uZywgd2VhazsKfSBGY01hdGNoZXI7CgovKgogKiBPcmRlciBpcyBzaWduaWZpY2FudCwgaXQgZGVmaW5lcyB0aGUgcHJlY2VkZW5jZSBvZgogKiBlYWNoIHZhbHVlLCBlYXJsaWVyIHZhbHVlcyBhcmUgbW9yZSBzaWduaWZpY2FudCB0aGFuCiAqIGxhdGVyIHZhbHVlcwogKi8Kc3RhdGljIEZjTWF0Y2hlciBfRmNNYXRjaGVycyBbXSA9IHsKICAgIHsgRkNfRk9VTkRSWSwJRmNDb21wYXJlU3RyaW5nLAkwLCAwIH0sCiNkZWZpbmUgTUFUQ0hfRk9VTkRSWQkgICAgMAogICAgCiAgICB7IEZDX0NIQVJTRVQsCUZjQ29tcGFyZUNoYXJTZXQsCTEsIDEgfSwKI2RlZmluZSBNQVRDSF9DSEFSU0VUCSAgICAxCiAgICAKICAgIHsgRkNfRkFNSUxZLCAgICAJRmNDb21wYXJlRmFtaWx5LAkyLCA0IH0sCiNkZWZpbmUgTUFUQ0hfRkFNSUxZCSAgICAyCiAgICAKICAgIHsgRkNfTEFORywJCUZjQ29tcGFyZUxhbmcsCQkzLCAzIH0sCiNkZWZpbmUgTUFUQ0hfTEFORwkgICAgMwogICAgCiAgICB7IEZDX1NQQUNJTkcsCUZjQ29tcGFyZU51bWJlciwJNSwgNSB9LAojZGVmaW5lIE1BVENIX1NQQUNJTkcJICAgIDQKICAgIAogICAgeyBGQ19QSVhFTF9TSVpFLAlGY0NvbXBhcmVTaXplLAkJNiwgNiB9LAojZGVmaW5lIE1BVENIX1BJWEVMX1NJWkUgICAgNQogICAgCiAgICB7IEZDX1NUWUxFLAkJRmNDb21wYXJlU3RyaW5nLAk3LCA3IH0sCiNkZWZpbmUgTUFUQ0hfU1RZTEUJICAgIDYKICAgIAogICAgeyBGQ19TTEFOVCwJCUZjQ29tcGFyZU51bWJlciwJOCwgOCB9LAojZGVmaW5lIE1BVENIX1NMQU5UCSAgICA3CiAgICAKICAgIHsgRkNfV0VJR0hULAlGY0NvbXBhcmVOdW1iZXIsCTksIDkgfSwKI2RlZmluZSBNQVRDSF9XRUlHSFQJICAgIDgKICAgIAogICAgeyBGQ19XSURUSCwJCUZjQ29tcGFyZU51bWJlciwJMTAsIDEwIH0sCiNkZWZpbmUgTUFUQ0hfV0lEVEgJICAgIDkKICAgIAogICAgeyBGQ19BTlRJQUxJQVMsCUZjQ29tcGFyZUJvb2wsCQkxMSwgMTEgfSwKI2RlZmluZSBNQVRDSF9BTlRJQUxJQVMJICAgIDEwCiAgICAKICAgIHsgRkNfUkFTVEVSSVpFUiwJRmNDb21wYXJlU3RyaW5nLAkxMiwgMTIgfSwKI2RlZmluZSBNQVRDSF9SQVNURVJJWkVSICAgIDExCiAgICAKICAgIHsgRkNfT1VUTElORSwJRmNDb21wYXJlQm9vbCwJCTEzLCAxMyB9LAojZGVmaW5lIE1BVENIX09VVExJTkUJICAgIDEyCgogICAgeyBGQ19GT05UVkVSU0lPTiwJRmNDb21wYXJlTnVtYmVyLAkxNCwgMTQgfSwKI2RlZmluZSBNQVRDSF9GT05UVkVSU0lPTiAgIDEzCn07CgojZGVmaW5lIE5VTV9NQVRDSF9WQUxVRVMgICAgMTUKCnN0YXRpYyBGY0Jvb2wKRmNDb21wYXJlVmFsdWVMaXN0IChjb25zdCBjaGFyICAqb2JqZWN0LAoJCSAgICBGY1ZhbHVlTGlzdAkqdjFvcmlnLAkvKiBwYXR0ZXJuICovCgkJICAgIEZjVmFsdWVMaXN0ICp2Mm9yaWcsCS8qIHRhcmdldCAqLwoJCSAgICBGY1ZhbHVlCSpiZXN0VmFsdWUsCgkJICAgIGRvdWJsZQkqdmFsdWUsCgkJICAgIEZjUmVzdWx0CSpyZXN1bHQpCnsKICAgIEZjVmFsdWVMaXN0ICAgICp2MSwgKnYyOwogICAgZG91YmxlICAgIAkgICAgdiwgYmVzdCwgYmVzdFN0cm9uZywgYmVzdFdlYWs7CiAgICBpbnQJCSAgICBpOwogICAgaW50CQkgICAgajsKICAgIAogICAgLyoKICAgICAqIExvY2F0ZSB0aGUgcG9zc2libGUgbWF0Y2hpbmcgZW50cnkgYnkgZXhhbWluaW5nIHRoZQogICAgICogZmlyc3QgZmV3IGNoYXJhY3RlcnMgaW4gb2JqZWN0CiAgICAgKi8KICAgIGkgPSAtMTsKICAgIHN3aXRjaCAoRmNUb0xvd2VyIChvYmplY3RbMF0pKSB7CiAgICBjYXNlICdmJzoKCXN3aXRjaCAoRmNUb0xvd2VyIChvYmplY3RbMV0pKSB7CgljYXNlICdvJzoKCSAgICBzd2l0Y2ggKEZjVG9Mb3dlciAob2JqZWN0WzJdKSkgewoJICAgIGNhc2UgJ3UnOgoJCWkgPSBNQVRDSF9GT1VORFJZOyBicmVhazsKCSAgICBjYXNlICduJzoKCQlpID0gTUFUQ0hfRk9OVFZFUlNJT047IGJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgJ2EnOgoJICAgIGkgPSBNQVRDSF9GQU1JTFk7IGJyZWFrOwoJfQoJYnJlYWs7CiAgICBjYXNlICdjJzoKCWkgPSBNQVRDSF9DSEFSU0VUOyBicmVhazsKICAgIGNhc2UgJ2EnOgoJaSA9IE1BVENIX0FOVElBTElBUzsgYnJlYWs7CiAgICBjYXNlICdsJzoKCWkgPSBNQVRDSF9MQU5HOyBicmVhazsKICAgIGNhc2UgJ3MnOgoJc3dpdGNoIChGY1RvTG93ZXIgKG9iamVjdFsxXSkpIHsKCWNhc2UgJ3AnOgoJICAgIGkgPSBNQVRDSF9TUEFDSU5HOyBicmVhazsKCWNhc2UgJ3QnOgoJICAgIGkgPSBNQVRDSF9TVFlMRTsgYnJlYWs7CgljYXNlICdsJzoKCSAgICBpID0gTUFUQ0hfU0xBTlQ7IGJyZWFrOwoJfQoJYnJlYWs7CiAgICBjYXNlICdwJzoKCWkgPSBNQVRDSF9QSVhFTF9TSVpFOyBicmVhazsKICAgIGNhc2UgJ3cnOgoJc3dpdGNoIChGY1RvTG93ZXIgKG9iamVjdFsxXSkpIHsKCWNhc2UgJ2knOgoJICAgIGkgPSBNQVRDSF9XSURUSDsgYnJlYWs7CgljYXNlICdlJzoKCSAgICBpID0gTUFUQ0hfV0VJR0hUOyBicmVhazsKCX0KCWJyZWFrOwogICAgY2FzZSAncic6CglpID0gTUFUQ0hfUkFTVEVSSVpFUjsgYnJlYWs7CiAgICBjYXNlICdvJzoKCWkgPSBNQVRDSF9PVVRMSU5FOyBicmVhazsKICAgIH0KICAgIGlmIChpID09IC0xIHx8IAoJRmNTdHJDbXBJZ25vcmVDYXNlICgoRmNDaGFyOCAqKSBfRmNNYXRjaGVyc1tpXS5vYmplY3QsCgkJCSAgICAoRmNDaGFyOCAqKSBvYmplY3QpICE9IDApCiAgICB7CglpZiAoYmVzdFZhbHVlKQoJICAgICpiZXN0VmFsdWUgPSB2Mm9yaWctPnZhbHVlOwoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KI2lmIDAKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTUFUQ0hFUjsgaSsrKQogICAgewoJaWYgKCFGY1N0ckNtcElnbm9yZUNhc2UgKChGY0NoYXI4ICopIF9GY01hdGNoZXJzW2ldLm9iamVjdCwKCQkJCSAoRmNDaGFyOCAqKSBvYmplY3QpKQoJICAgIGJyZWFrOwogICAgfQogICAgaWYgKGkgPT0gTlVNX01BVENIRVIpCiAgICB7CglpZiAoYmVzdFZhbHVlKQoJICAgICpiZXN0VmFsdWUgPSB2Mm9yaWctPnZhbHVlOwoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KI2VuZGlmCiAgICBiZXN0ID0gMWU5OTsKICAgIGJlc3RTdHJvbmcgPSAxZTk5OwogICAgYmVzdFdlYWsgPSAxZTk5OwogICAgaiA9IDA7CiAgICBmb3IgKHYxID0gdjFvcmlnOyB2MTsgdjEgPSB2MS0+bmV4dCkKICAgIHsKCWZvciAodjIgPSB2Mm9yaWc7IHYyOyB2MiA9IHYyLT5uZXh0KQoJewoJICAgIHYgPSAoKl9GY01hdGNoZXJzW2ldLmNvbXBhcmUpIChfRmNNYXRjaGVyc1tpXS5vYmplY3QsCgkJCQkJICAgIHYxLT52YWx1ZSwKCQkJCQkgICAgdjItPnZhbHVlKTsKCSAgICBpZiAodiA8IDApCgkgICAgewoJCSpyZXN1bHQgPSBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICB9CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfTUFUQ0hWKQoJCXByaW50ZiAoIiB2ICVnIGogJWQgIiwgdiwgaik7CgkgICAgdiA9IHYgKiAxMDAgKyBqOwoJICAgIGlmICh2IDwgYmVzdCkKCSAgICB7CgkJaWYgKGJlc3RWYWx1ZSkKCQkgICAgKmJlc3RWYWx1ZSA9IHYyLT52YWx1ZTsKCQliZXN0ID0gdjsKCSAgICB9CgkgICAgaWYgKHYxLT5iaW5kaW5nID09IEZjVmFsdWVCaW5kaW5nU3Ryb25nKQoJICAgIHsKCQlpZiAodiA8IGJlc3RTdHJvbmcpCgkJICAgIGJlc3RTdHJvbmcgPSB2OwoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCWlmICh2IDwgYmVzdFdlYWspCgkJICAgIGJlc3RXZWFrID0gdjsKCSAgICB9Cgl9CglqKys7CiAgICB9CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19NQVRDSFYpCiAgICB7CglwcmludGYgKCIgJXM6ICVnICIsIG9iamVjdCwgYmVzdCk7CglGY1ZhbHVlTGlzdFByaW50ICh2MW9yaWcpOwoJcHJpbnRmICgiLCAiKTsKCUZjVmFsdWVMaXN0UHJpbnQgKHYyb3JpZyk7CglwcmludGYgKCJcbiIpOwogICAgfQogICAgaWYgKHZhbHVlKQogICAgewoJaW50IHdlYWsgICAgPSBfRmNNYXRjaGVyc1tpXS53ZWFrOwoJaW50IHN0cm9uZyAgPSBfRmNNYXRjaGVyc1tpXS5zdHJvbmc7CglpZiAod2VhayA9PSBzdHJvbmcpCgkgICAgdmFsdWVbc3Ryb25nXSArPSBiZXN0OwoJZWxzZQoJewoJICAgIHZhbHVlW3dlYWtdICs9IGJlc3RXZWFrOwoJICAgIHZhbHVlW3N0cm9uZ10gKz0gYmVzdFN0cm9uZzsKCX0KICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCi8qCiAqIFJldHVybiBhIHZhbHVlIGluZGljYXRpbmcgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIHR3byBsaXN0cyBvZgogKiB2YWx1ZXMKICovCgpzdGF0aWMgRmNCb29sCkZjQ29tcGFyZSAoRmNQYXR0ZXJuCSpwYXQsCgkgICBGY1BhdHRlcm4JKmZudCwKCSAgIGRvdWJsZQkqdmFsdWUsCgkgICBGY1Jlc3VsdAkqcmVzdWx0KQp7CiAgICBpbnQJCSAgICBpLCBpMSwgaTI7CiAgICAKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTUFUQ0hfVkFMVUVTOyBpKyspCgl2YWx1ZVtpXSA9IDAuMDsKICAgIAogICAgaTEgPSAwOwogICAgaTIgPSAwOwogICAgd2hpbGUgKGkxIDwgcGF0LT5udW0gJiYgaTIgPCBmbnQtPm51bSkKICAgIHsKCWkgPSBzdHJjbXAgKHBhdC0+ZWx0c1tpMV0ub2JqZWN0LCBmbnQtPmVsdHNbaTJdLm9iamVjdCk7CglpZiAoaSA+IDApCgkgICAgaTIrKzsKCWVsc2UgaWYgKGkgPCAwKQoJICAgIGkxKys7CgllbHNlCgl7CgkgICAgaWYgKCFGY0NvbXBhcmVWYWx1ZUxpc3QgKHBhdC0+ZWx0c1tpMV0ub2JqZWN0LAoJCQkJICAgICBwYXQtPmVsdHNbaTFdLnZhbHVlcywKCQkJCSAgICAgZm50LT5lbHRzW2kyXS52YWx1ZXMsCgkJCQkgICAgIDAsCgkJCQkgICAgIHZhbHVlLAoJCQkJICAgICByZXN1bHQpKQoJCXJldHVybiBGY0ZhbHNlOwoJICAgIGkxKys7CgkgICAgaTIrKzsKCX0KICAgIH0KICAgIHJldHVybiBGY1RydWU7CiNpZiAwCiAgICBmb3IgKGkxID0gMDsgaTEgPCBwYXQtPm51bTsgaTErKykKICAgIHsKCWZvciAoaTIgPSAwOyBpMiA8IGZudC0+bnVtOyBpMisrKQoJewoJICAgIGlmICghc3RyY21wIChwYXQtPmVsdHNbaTFdLm9iamVjdCwgZm50LT5lbHRzW2kyXS5vYmplY3QpKQoJICAgIHsKCQlicmVhazsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwojZW5kaWYKfQoKRmNQYXR0ZXJuICoKRmNGb250UmVuZGVyUHJlcGFyZSAoRmNDb25maWcJICAgICpjb25maWcsCgkJICAgICBGY1BhdHRlcm4JICAgICpwYXQsCgkJICAgICBGY1BhdHRlcm4JICAgICpmb250KQp7CiAgICBGY1BhdHRlcm4JICAgICpuZXc7CiAgICBpbnQJCSAgICBpOwogICAgRmNQYXR0ZXJuRWx0ICAgICpmZSwgKnBlOwogICAgRmNWYWx1ZQkgICAgdjsKICAgIEZjUmVzdWx0CSAgICByZXN1bHQ7CiAgICAKICAgIG5ldyA9IEZjUGF0dGVybkNyZWF0ZSAoKTsKICAgIGlmICghbmV3KQoJcmV0dXJuIDA7CiAgICBmb3IgKGkgPSAwOyBpIDwgZm9udC0+bnVtOyBpKyspCiAgICB7CglmZSA9ICZmb250LT5lbHRzW2ldOwoJcGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwYXQsIGZlLT5vYmplY3QpOwoJaWYgKHBlKQoJewoJICAgIGlmICghRmNDb21wYXJlVmFsdWVMaXN0IChwZS0+b2JqZWN0LCBwZS0+dmFsdWVzLCAKCQkJCSAgICAgZmUtPnZhbHVlcywgJnYsIDAsICZyZXN1bHQpKQoJICAgIHsKCQlGY1BhdHRlcm5EZXN0cm95IChuZXcpOwoJCXJldHVybiAwOwoJICAgIH0KCX0KCWVsc2UKCSAgICB2ID0gZmUtPnZhbHVlcy0+dmFsdWU7CglGY1BhdHRlcm5BZGQgKG5ldywgZmUtPm9iamVjdCwgdiwgRmNGYWxzZSk7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgcGF0LT5udW07IGkrKykKICAgIHsKCXBlID0gJnBhdC0+ZWx0c1tpXTsKCWZlID0gRmNQYXR0ZXJuRmluZEVsdCAoZm9udCwgcGUtPm9iamVjdCk7CglpZiAoIWZlKQoJICAgIEZjUGF0dGVybkFkZCAobmV3LCBwZS0+b2JqZWN0LCBwZS0+dmFsdWVzLT52YWx1ZSwgRmNUcnVlKTsKICAgIH0KICAgIEZjQ29uZmlnU3Vic3RpdHV0ZVdpdGhQYXQgKGNvbmZpZywgbmV3LCBwYXQsIEZjTWF0Y2hGb250KTsKICAgIHJldHVybiBuZXc7Cn0KCkZjUGF0dGVybiAqCkZjRm9udFNldE1hdGNoIChGY0NvbmZpZyAgICAqY29uZmlnLAoJCUZjRm9udFNldCAgICoqc2V0cywKCQlpbnQJICAgIG5zZXRzLAoJCUZjUGF0dGVybiAgICpwLAoJCUZjUmVzdWx0ICAgICpyZXN1bHQpCnsKICAgIGRvdWJsZSAgICAJICAgIHNjb3JlW05VTV9NQVRDSF9WQUxVRVNdLCBiZXN0c2NvcmVbTlVNX01BVENIX1ZBTFVFU107CiAgICBpbnQJCSAgICBmOwogICAgRmNGb250U2V0CSAgICAqczsKICAgIEZjUGF0dGVybgkgICAgKmJlc3Q7CiAgICBpbnQJCSAgICBpOwogICAgaW50CQkgICAgc2V0OwoKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTUFUQ0hfVkFMVUVTOyBpKyspCgliZXN0c2NvcmVbaV0gPSAwOwogICAgYmVzdCA9IDA7CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19NQVRDSCkKICAgIHsKCXByaW50ZiAoIk1hdGNoICIpOwoJRmNQYXR0ZXJuUHJpbnQgKHApOwogICAgfQogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIGZvciAoc2V0ID0gMDsgc2V0IDwgbnNldHM7IHNldCsrKQogICAgewoJcyA9IHNldHNbc2V0XTsKCWlmICghcykKCSAgICBjb250aW51ZTsKCWZvciAoZiA9IDA7IGYgPCBzLT5uZm9udDsgZisrKQoJewoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX01BVENIVikKCSAgICB7CgkJcHJpbnRmICgiRm9udCAlZCAiLCBmKTsKCQlGY1BhdHRlcm5QcmludCAocy0+Zm9udHNbZl0pOwoJICAgIH0KCSAgICBpZiAoIUZjQ29tcGFyZSAocCwgcy0+Zm9udHNbZl0sIHNjb3JlLCByZXN1bHQpKQoJCXJldHVybiAwOwoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX01BVENIVikKCSAgICB7CgkJcHJpbnRmICgiU2NvcmUiKTsKCQlmb3IgKGkgPSAwOyBpIDwgTlVNX01BVENIX1ZBTFVFUzsgaSsrKQoJCXsKCQkgICAgcHJpbnRmICgiICVnIiwgc2NvcmVbaV0pOwoJCX0KCQlwcmludGYgKCJcbiIpOwoJICAgIH0KCSAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX01BVENIX1ZBTFVFUzsgaSsrKQoJICAgIHsKCQlpZiAoYmVzdCAmJiBiZXN0c2NvcmVbaV0gPCBzY29yZVtpXSkKCQkgICAgYnJlYWs7CgkJaWYgKCFiZXN0IHx8IHNjb3JlW2ldIDwgYmVzdHNjb3JlW2ldKQoJCXsKCQkgICAgZm9yIChpID0gMDsgaSA8IE5VTV9NQVRDSF9WQUxVRVM7IGkrKykKCQkJYmVzdHNjb3JlW2ldID0gc2NvcmVbaV07CgkJICAgIGJlc3QgPSBzLT5mb250c1tmXTsKCQkgICAgYnJlYWs7CgkJfQoJICAgIH0KCX0KICAgIH0KICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX01BVENIKQogICAgewoJcHJpbnRmICgiQmVzdCBzY29yZSIpOwoJZm9yIChpID0gMDsgaSA8IE5VTV9NQVRDSF9WQUxVRVM7IGkrKykKCSAgICBwcmludGYgKCIgJWciLCBiZXN0c2NvcmVbaV0pOwoJRmNQYXR0ZXJuUHJpbnQgKGJlc3QpOwogICAgfQogICAgaWYgKCFiZXN0KQogICAgewoJKnJlc3VsdCA9IEZjUmVzdWx0Tm9NYXRjaDsKCXJldHVybiAwOwogICAgfQogICAgcmV0dXJuIEZjRm9udFJlbmRlclByZXBhcmUgKGNvbmZpZywgcCwgYmVzdCk7Cn0KCkZjUGF0dGVybiAqCkZjRm9udE1hdGNoIChGY0NvbmZpZwkqY29uZmlnLAoJICAgICBGY1BhdHRlcm4JKnAsIAoJICAgICBGY1Jlc3VsdAkqcmVzdWx0KQp7CiAgICBGY0ZvbnRTZXQJKnNldHNbMl07CiAgICBpbnQJCW5zZXRzOwoKICAgIGlmICghY29uZmlnKQogICAgewoJY29uZmlnID0gRmNDb25maWdHZXRDdXJyZW50ICgpOwoJaWYgKCFjb25maWcpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICBuc2V0cyA9IDA7CiAgICBpZiAoY29uZmlnLT5mb250c1tGY1NldFN5c3RlbV0pCglzZXRzW25zZXRzKytdID0gY29uZmlnLT5mb250c1tGY1NldFN5c3RlbV07CiAgICBpZiAoY29uZmlnLT5mb250c1tGY1NldEFwcGxpY2F0aW9uXSkKCXNldHNbbnNldHMrK10gPSBjb25maWctPmZvbnRzW0ZjU2V0QXBwbGljYXRpb25dOwogICAgcmV0dXJuIEZjRm9udFNldE1hdGNoIChjb25maWcsIHNldHMsIG5zZXRzLCBwLCByZXN1bHQpOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNTb3J0Tm9kZSB7CiAgICBGY1BhdHRlcm4JKnBhdHRlcm47CiAgICBkb3VibGUJc2NvcmVbTlVNX01BVENIX1ZBTFVFU107Cn0gRmNTb3J0Tm9kZTsKCnN0YXRpYyBpbnQKRmNTb3J0Q29tcGFyZSAoY29uc3Qgdm9pZCAqYWEsIGNvbnN0IHZvaWQgKmFiKQp7CiAgICBGY1NvcnROb2RlICAqYSA9ICooRmNTb3J0Tm9kZSAqKikgYWE7CiAgICBGY1NvcnROb2RlICAqYiA9ICooRmNTb3J0Tm9kZSAqKikgYWI7CiAgICBkb3VibGUJKmFzID0gJmEtPnNjb3JlWzBdOwogICAgZG91YmxlCSpicyA9ICZiLT5zY29yZVswXTsKICAgIGRvdWJsZQlhZCA9IDAsIGJkID0gMDsKICAgIGludCAgICAgICAgIGk7CgogICAgaSA9IE5VTV9NQVRDSF9WQUxVRVM7CiAgICB3aGlsZSAoaS0tICYmIChhZCA9ICphcysrKSA9PSAoYmQgPSAqYnMrKykpCgk7CiAgICByZXR1cm4gYWQgPCBiZCA/IC0xIDogYWQgPiBiZCA/IDEgOiAwOwp9CgpzdGF0aWMgRmNCb29sCkZjU29ydFdhbGsgKEZjU29ydE5vZGUgKipuLCBpbnQgbm5vZGUsIEZjRm9udFNldCAqZnMsIEZjQ2hhclNldCAqKmNzLCBGY0Jvb2wgdHJpbSkKewogICAgRmNDaGFyU2V0CSpuY3M7CiAgICBGY1NvcnROb2RlCSpub2RlOwoKICAgIHdoaWxlIChubm9kZS0tKQogICAgewoJbm9kZSA9ICpuKys7CglpZiAoRmNQYXR0ZXJuR2V0Q2hhclNldCAobm9kZS0+cGF0dGVybiwgRkNfQ0hBUlNFVCwgMCwgJm5jcykgPT0gCgkgICAgRmNSZXN1bHRNYXRjaCkKCXsKCSAgICAvKgoJICAgICAqIElmIHRoaXMgZm9udCBpc24ndCBhIHN1YnNldCBvZiB0aGUgcHJldmlvdXMgZm9udHMsCgkgICAgICogYWRkIGl0IHRvIHRoZSBsaXN0CgkgICAgICovCgkgICAgaWYgKCF0cmltIHx8ICEqY3MgfHwgIUZjQ2hhclNldElzU3Vic2V0IChuY3MsICpjcykpCgkgICAgewoJCWlmICgqY3MpCgkJewoJCSAgICBuY3MgPSBGY0NoYXJTZXRVbmlvbiAobmNzLCAqY3MpOwoJCSAgICBpZiAoIW5jcykKCQkJcmV0dXJuIEZjRmFsc2U7CgkJICAgIEZjQ2hhclNldERlc3Ryb3kgKCpjcyk7CgkJfQoJCWVsc2UKCQkgICAgbmNzID0gRmNDaGFyU2V0Q29weSAobmNzKTsKCQkqY3MgPSBuY3M7CgkJRmNQYXR0ZXJuUmVmZXJlbmNlIChub2RlLT5wYXR0ZXJuKTsKCQlpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19NQVRDSCkKCQl7CgkJICAgIHByaW50ZiAoIkFkZCAiKTsKCQkgICAgRmNQYXR0ZXJuUHJpbnQgKG5vZGUtPnBhdHRlcm4pOwoJCX0KCQlpZiAoIUZjRm9udFNldEFkZCAoZnMsIG5vZGUtPnBhdHRlcm4pKQoJCXsKCQkgICAgRmNQYXR0ZXJuRGVzdHJveSAobm9kZS0+cGF0dGVybik7CgkJICAgIHJldHVybiBGY0ZhbHNlOwoJCX0KCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp2b2lkCkZjRm9udFNldFNvcnREZXN0cm95IChGY0ZvbnRTZXQgKmZzKQp7CiAgICBGY0ZvbnRTZXREZXN0cm95IChmcyk7Cn0KCkZjRm9udFNldCAqCkZjRm9udFNldFNvcnQgKEZjQ29uZmlnCSAgICAqY29uZmlnLAoJICAgICAgIEZjRm9udFNldCAgICAqKnNldHMsCgkgICAgICAgaW50CSAgICBuc2V0cywKCSAgICAgICBGY1BhdHRlcm4gICAgKnAsCgkgICAgICAgRmNCb29sCSAgICB0cmltLAoJICAgICAgIEZjQ2hhclNldCAgICAqKmNzcCwKCSAgICAgICBGY1Jlc3VsdAkgICAgKnJlc3VsdCkKewogICAgRmNGb250U2V0CSAgICAqcmV0OwogICAgRmNGb250U2V0CSAgICAqczsKICAgIEZjU29ydE5vZGUJICAgICpub2RlczsKICAgIEZjU29ydE5vZGUJICAgICoqbm9kZXBzLCAqKm5vZGVwOwogICAgaW50CQkgICAgbm5vZGVzOwogICAgRmNTb3J0Tm9kZQkgICAgKm5ldzsKICAgIEZjQ2hhclNldAkgICAgKmNzOwogICAgaW50CQkgICAgc2V0OwogICAgaW50CQkgICAgZjsKICAgIGludAkJICAgIGk7CgogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfTUFUQ0gpCiAgICB7CglwcmludGYgKCJTb3J0ICIpOwoJRmNQYXR0ZXJuUHJpbnQgKHApOwogICAgfQogICAgbm5vZGVzID0gMDsKICAgIGZvciAoc2V0ID0gMDsgc2V0IDwgbnNldHM7IHNldCsrKQogICAgewoJcyA9IHNldHNbc2V0XTsKCWlmICghcykKCSAgICBjb250aW51ZTsKCW5ub2RlcyArPSBzLT5uZm9udDsKICAgIH0KICAgIGlmICghbm5vZGVzKQoJZ290byBiYWlsMDsKICAgIC8qIGZyZWVkIGJlbG93ICovCiAgICBub2RlcyA9IG1hbGxvYyAobm5vZGVzICogc2l6ZW9mIChGY1NvcnROb2RlKSArIG5ub2RlcyAqIHNpemVvZiAoRmNTb3J0Tm9kZSAqKSk7CiAgICBpZiAoIW5vZGVzKQoJZ290byBiYWlsMDsKICAgIG5vZGVwcyA9IChGY1NvcnROb2RlICoqKSAobm9kZXMgKyBubm9kZXMpOwogICAgCiAgICBuZXcgPSBub2RlczsKICAgIG5vZGVwID0gbm9kZXBzOwogICAgZm9yIChzZXQgPSAwOyBzZXQgPCBuc2V0czsgc2V0KyspCiAgICB7CglzID0gc2V0c1tzZXRdOwoJaWYgKCFzKQoJICAgIGNvbnRpbnVlOwoJZm9yIChmID0gMDsgZiA8IHMtPm5mb250OyBmKyspCgl7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfTUFUQ0hWKQoJICAgIHsKCQlwcmludGYgKCJGb250ICVkICIsIGYpOwoJCUZjUGF0dGVyblByaW50IChzLT5mb250c1tmXSk7CgkgICAgfQoJICAgIG5ldy0+cGF0dGVybiA9IHMtPmZvbnRzW2ZdOwoJICAgIGlmICghRmNDb21wYXJlIChwLCBuZXctPnBhdHRlcm4sIG5ldy0+c2NvcmUsIHJlc3VsdCkpCgkJZ290byBiYWlsMTsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19NQVRDSFYpCgkgICAgewoJCXByaW50ZiAoIlNjb3JlIik7CgkJZm9yIChpID0gMDsgaSA8IE5VTV9NQVRDSF9WQUxVRVM7IGkrKykKCQl7CgkJICAgIHByaW50ZiAoIiAlZyIsIG5ldy0+c2NvcmVbaV0pOwoJCX0KCQlwcmludGYgKCJcbiIpOwoJICAgIH0KCSAgICAqbm9kZXAgPSBuZXc7CgkgICAgbmV3Kys7CgkgICAgbm9kZXArKzsKCX0KICAgIH0KCiAgICBubm9kZXMgPSBuZXcgLSBub2RlczsKICAgIAogICAgcXNvcnQgKG5vZGVwcywgbm5vZGVzLCBzaXplb2YgKEZjU29ydE5vZGUgKiksCgkgICBGY1NvcnRDb21wYXJlKTsKCiAgICByZXQgPSBGY0ZvbnRTZXRDcmVhdGUgKCk7CiAgICBpZiAoIXJldCkKCWdvdG8gYmFpbDE7CgogICAgY3MgPSAwOwoKICAgIGlmICghRmNTb3J0V2FsayAobm9kZXBzLCBubm9kZXMsIHJldCwgJmNzLCB0cmltKSkKCWdvdG8gYmFpbDI7CgogICAgaWYgKGNzcCkKCSpjc3AgPSBjczsKICAgIGVsc2UKCUZjQ2hhclNldERlc3Ryb3kgKGNzKTsKCiAgICBmcmVlIChub2Rlcyk7CgogICAgcmV0dXJuIHJldDsKCmJhaWwyOgogICAgaWYgKGNzKQoJRmNDaGFyU2V0RGVzdHJveSAoY3MpOwogICAgRmNGb250U2V0RGVzdHJveSAocmV0KTsKYmFpbDE6CiAgICBmcmVlIChub2Rlcyk7CmJhaWwwOgogICAgcmV0dXJuIDA7Cn0KCkZjRm9udFNldCAqCkZjRm9udFNvcnQgKEZjQ29uZmlnCSpjb25maWcsCgkgICAgRmNQYXR0ZXJuCSpwLCAKCSAgICBGY0Jvb2wJdHJpbSwKCSAgICBGY0NoYXJTZXQJKipjc3AsCgkgICAgRmNSZXN1bHQJKnJlc3VsdCkKewogICAgRmNGb250U2V0CSpzZXRzWzJdOwogICAgaW50CQluc2V0czsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgbnNldHMgPSAwOwogICAgaWYgKGNvbmZpZy0+Zm9udHNbRmNTZXRTeXN0ZW1dKQoJc2V0c1tuc2V0cysrXSA9IGNvbmZpZy0+Zm9udHNbRmNTZXRTeXN0ZW1dOwogICAgaWYgKGNvbmZpZy0+Zm9udHNbRmNTZXRBcHBsaWNhdGlvbl0pCglzZXRzW25zZXRzKytdID0gY29uZmlnLT5mb250c1tGY1NldEFwcGxpY2F0aW9uXTsKICAgIHJldHVybiBGY0ZvbnRTZXRTb3J0IChjb25maWcsIHNldHMsIG5zZXRzLCBwLCB0cmltLCBjc3AsIHJlc3VsdCk7Cn0K