LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNpbml0LmMsdiAxLjcgMjAwMi8wOC8yMiAwNzozNjo0NCBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMSBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlICJmY2ludC5oIgoKc3RhdGljIEZjQ29uZmlnICoKRmNJbml0RmFsbGJhY2tDb25maWcgKHZvaWQpCnsKICAgIEZjQ29uZmlnCSpjb25maWc7CgogICAgY29uZmlnID0gRmNDb25maWdDcmVhdGUgKCk7CiAgICBpZiAoIWNvbmZpZykKCWdvdG8gYmFpbDA7CiAgICBpZiAoIUZjQ29uZmlnQWRkRGlyIChjb25maWcsIChGY0NoYXI4ICopIEZDX0RFRkFVTFRfRk9OVFMpKQoJZ290byBiYWlsMTsKICAgIHJldHVybiBjb25maWc7CgpiYWlsMToKICAgIEZjQ29uZmlnRGVzdHJveSAoY29uZmlnKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKaW50CkZjR2V0VmVyc2lvbiAodm9pZCkKewogICAgcmV0dXJuIEZDX1ZFUlNJT047Cn0KCi8qCiAqIExvYWQgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZXMKICovCkZjQ29uZmlnICoKRmNJbml0TG9hZENvbmZpZyAodm9pZCkKewogICAgRmNDb25maWcJKmNvbmZpZzsKICAgIAogICAgY29uZmlnID0gRmNDb25maWdDcmVhdGUgKCk7CiAgICBpZiAoIWNvbmZpZykKCXJldHVybiBGY0ZhbHNlOwogICAgCiAgICBpZiAoIUZjQ29uZmlnUGFyc2VBbmRMb2FkIChjb25maWcsIDAsIEZjVHJ1ZSkpCiAgICB7CglGY0NvbmZpZ0Rlc3Ryb3kgKGNvbmZpZyk7CglyZXR1cm4gRmNJbml0RmFsbGJhY2tDb25maWcgKCk7CiAgICB9CgogICAgcmV0dXJuIGNvbmZpZzsKfQoKLyoKICogTG9hZCB0aGUgY29uZmlndXJhdGlvbiBmaWxlcyBhbmQgc2NhbiBmb3IgYXZhaWxhYmxlIGZvbnRzCiAqLwpGY0NvbmZpZyAqCkZjSW5pdExvYWRDb25maWdBbmRGb250cyAodm9pZCkKewogICAgRmNDb25maWcJKmNvbmZpZyA9IEZjSW5pdExvYWRDb25maWcgKCk7CgogICAgaWYgKCFjb25maWcpCglyZXR1cm4gMDsKICAgIGlmICghRmNDb25maWdCdWlsZEZvbnRzIChjb25maWcpKQogICAgewoJRmNDb25maWdEZXN0cm95IChjb25maWcpOwoJcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gY29uZmlnOwp9CgovKgogKiBJbml0aWFsaXplIHRoZSBkZWZhdWx0IGxpYnJhcnkgY29uZmlndXJhdGlvbgogKi8KRmNCb29sCkZjSW5pdCAodm9pZCkKewogICAgRmNDb25maWcJKmNvbmZpZzsKCiAgICBpZiAoX2ZjQ29uZmlnKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIGNvbmZpZyA9IEZjSW5pdExvYWRDb25maWdBbmRGb250cyAoKTsKICAgIGlmICghY29uZmlnKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIEZjQ29uZmlnU2V0Q3VycmVudCAoY29uZmlnKTsKICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfTUVNT1JZKQoJRmNNZW1SZXBvcnQgKCk7CiAgICByZXR1cm4gRmNUcnVlOwp9CgovKgogKiBSZXJlYWQgdGhlIGNvbmZpZ3VyYXRpb24gYW5kIGF2YWlsYWJsZSBmb250IGxpc3RzCiAqLwpGY0Jvb2wKRmNJbml0UmVpbml0aWFsaXplICh2b2lkKQp7CiAgICBGY0NvbmZpZwkqY29uZmlnOwoKICAgIGNvbmZpZyA9IEZjSW5pdExvYWRDb25maWdBbmRGb250cyAoKTsKICAgIGlmICghY29uZmlnKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBGY0NvbmZpZ1NldEN1cnJlbnQgKGNvbmZpZyk7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNJbml0QnJpbmdVcHRvRGF0ZSAodm9pZCkKewogICAgRmNDb25maWcJKmNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKICAgIHRpbWVfdAlub3c7CgogICAgLyoKICAgICAqIHJlc2NhbkludGVydmFsID09IDAgZGlzYWJsZXMgYXV0b21hdGljIHVwIHRvIGRhdGUKICAgICAqLwogICAgaWYgKGNvbmZpZy0+cmVzY2FuSW50ZXJ2YWwgPT0gMCkKCXJldHVybiBGY1RydWU7CiAgICAvKgogICAgICogQ2hlY2sgbm8gbW9yZSBvZnRlbiB0aGFuIHJlc2NhbkludGVydmFsIHNlY29uZHMKICAgICAqLwogICAgbm93ID0gdGltZSAoMCk7CiAgICBpZiAoY29uZmlnLT5yZXNjYW5UaW1lICsgY29uZmlnLT5yZXNjYW5JbnRlcnZhbCAtIG5vdyA+IDApCglyZXR1cm4gRmNUcnVlOwogICAgLyoKICAgICAqIElmIHVwIHRvIGRhdGUsIGRvbid0IHJlbG9hZCBjb25maWd1cmF0aW9uCiAgICAgKi8KICAgIGlmIChGY0NvbmZpZ1VwdG9EYXRlICgwKSkKCXJldHVybiBGY1RydWU7CiAgICByZXR1cm4gRmNJbml0UmVpbml0aWFsaXplICgpOwp9CgpzdGF0aWMgc3RydWN0IHsKICAgIGNoYXIgICAgKm5hbWU7CiAgICBpbnQJICAgIGFsbG9jX2NvdW50OwogICAgaW50CSAgICBhbGxvY19tZW07CiAgICBpbnQJICAgIGZyZWVfY291bnQ7CiAgICBpbnQJICAgIGZyZWVfbWVtOwp9IEZjSW5Vc2VbRkNfTUVNX05VTV0gPSB7CiAgICB7ICJjaGFyc2V0IiB9LAogICAgeyAiY2hhcmxlYWYiIH0sCiAgICB7ICJmb250c2V0IiB9LAogICAgeyAiZm9udHB0ciIgfSwKICAgIHsgIm9iamVjdHNldCIgfSwKICAgIHsgIm9iamVjdHB0ciIgfSwKICAgIHsgIm1hdHJpeCIgfSwKICAgIHsgInBhdHRlcm4iIH0sCiAgICB7ICJwYXRlbHQiIH0sCiAgICB7ICJ2YWxsaXN0IiB9LAogICAgeyAic3Vic3RhdGUiIH0sCiAgICB7ICJzdHJpbmciIH0sCiAgICB7ICJsaXN0YnVjayIgfSwKICAgIHsgInN0cnNldCIgfSwKICAgIHsgInN0cmxpc3QiIH0sCiAgICB7ICJjb25maWciIH0sCiAgICB7ICJsYW5nc2V0IiB9LAogICAgeyAiYXRvbWljIiB9LAogICAgeyAiYmxhbmtzIiB9LAogICAgeyAiY2FjaGUiIH0sCiAgICB7ICJzdHJidWYiIH0sCiAgICB7ICJzdWJzdCIgfSwKICAgIHsgIm9iamVjdHR5cGUiIH0sCiAgICB7ICJjb25zdGFudCIgfSwKICAgIHsgInRlc3QiIH0sCiAgICB7ICJleHByIiB9LAogICAgeyAidnN0YWNrIiB9LAogICAgeyAiYXR0ciIgfSwKICAgIHsgInBzdGFjayIgfSwKfTsKCnN0YXRpYyBpbnQgIEZjQWxsb2NDb3VudCwgRmNBbGxvY01lbTsKc3RhdGljIGludCAgRmNGcmVlQ291bnQsIEZjRnJlZU1lbTsKCnN0YXRpYyBpbnQgIEZjTWVtTm90aWNlID0gMSoxMDI0KjEwMjQ7CgpzdGF0aWMgaW50ICBGY0FsbG9jTm90aWZ5LCBGY0ZyZWVOb3RpZnk7Cgp2b2lkCkZjVmFsdWVMaXN0UmVwb3J0ICh2b2lkKTsKCnZvaWQKRmNNZW1SZXBvcnQgKHZvaWQpCnsKICAgIGludAlpOwogICAgcHJpbnRmICgiRmMgTWVtb3J5IFVzYWdlOlxuIik7CiAgICBwcmludGYgKCJcdCAgIFdoaWNoICAgICAgIEFsbG9jICAgICAgICAgICBGcmVlICAgICAgICAgICBBY3RpdmVcbiIpOwogICAgcHJpbnRmICgiXHQgICAgICAgICAgIGNvdW50ICAgYnl0ZXMgICBjb3VudCAgIGJ5dGVzICAgY291bnQgICBieXRlc1xuIik7CiAgICBmb3IgKGkgPSAwOyBpIDwgRkNfTUVNX05VTTsgaSsrKQoJcHJpbnRmICgiXHQlOC44cyU4ZCU4ZCU4ZCU4ZCU4ZCU4ZFxuIiwKCQlGY0luVXNlW2ldLm5hbWUsCgkJRmNJblVzZVtpXS5hbGxvY19jb3VudCwgRmNJblVzZVtpXS5hbGxvY19tZW0sCgkJRmNJblVzZVtpXS5mcmVlX2NvdW50LCBGY0luVXNlW2ldLmZyZWVfbWVtLAoJCUZjSW5Vc2VbaV0uYWxsb2NfY291bnQgLSBGY0luVXNlW2ldLmZyZWVfY291bnQsCgkJRmNJblVzZVtpXS5hbGxvY19tZW0gLSBGY0luVXNlW2ldLmZyZWVfbWVtKTsKICAgIHByaW50ZiAoIlx0JTguOHMlOGQlOGQlOGQlOGQlOGQlOGRcbiIsCgkgICAgIlRvdGFsIiwKCSAgICBGY0FsbG9jQ291bnQsIEZjQWxsb2NNZW0sCgkgICAgRmNGcmVlQ291bnQsIEZjRnJlZU1lbSwKCSAgICBGY0FsbG9jQ291bnQgLSBGY0ZyZWVDb3VudCwKCSAgICBGY0FsbG9jTWVtIC0gRmNGcmVlTWVtKTsKICAgIEZjQWxsb2NOb3RpZnkgPSAwOwogICAgRmNGcmVlTm90aWZ5ID0gMDsKICAgIEZjVmFsdWVMaXN0UmVwb3J0ICgpOwp9Cgp2b2lkCkZjTWVtQWxsb2MgKGludCBraW5kLCBpbnQgc2l6ZSkKewogICAgaWYgKEZjRGVidWcoKSAmIEZDX0RCR19NRU1PUlkpCiAgICB7CglGY0luVXNlW2tpbmRdLmFsbG9jX2NvdW50Kys7CglGY0luVXNlW2tpbmRdLmFsbG9jX21lbSArPSBzaXplOwoJRmNBbGxvY0NvdW50Kys7CglGY0FsbG9jTWVtICs9IHNpemU7CglGY0FsbG9jTm90aWZ5ICs9IHNpemU7CglpZiAoRmNBbGxvY05vdGlmeSA+IEZjTWVtTm90aWNlKQoJICAgIEZjTWVtUmVwb3J0ICgpOwogICAgfQp9Cgp2b2lkCkZjTWVtRnJlZSAoaW50IGtpbmQsIGludCBzaXplKQp7CiAgICBpZiAoRmNEZWJ1ZygpICYgRkNfREJHX01FTU9SWSkKICAgIHsKCUZjSW5Vc2Vba2luZF0uZnJlZV9jb3VudCsrOwoJRmNJblVzZVtraW5kXS5mcmVlX21lbSArPSBzaXplOwoJRmNGcmVlQ291bnQrKzsKCUZjRnJlZU1lbSArPSBzaXplOwoJRmNGcmVlTm90aWZ5ICs9IHNpemU7CglpZiAoRmNGcmVlTm90aWZ5ID4gRmNNZW1Ob3RpY2UpCgkgICAgRmNNZW1SZXBvcnQgKCk7CiAgICB9Cn0K