LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNpbml0LmMsdiAxLjcgMjAwMi8wOC8yMiAwNzozNjo0NCBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMSBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlICJmY2ludC5oIgoKc3RhdGljIEZjQ29uZmlnICoKRmNJbml0RmFsbGJhY2tDb25maWcgKHZvaWQpCnsKICAgIEZjQ29uZmlnCSpjb25maWc7CgogICAgY29uZmlnID0gRmNDb25maWdDcmVhdGUgKCk7CiAgICBpZiAoIWNvbmZpZykKCWdvdG8gYmFpbDA7CiAgICBpZiAoIUZjQ29uZmlnQWRkRGlyIChjb25maWcsIChGY0NoYXI4ICopIEZDX0RFRkFVTFRfRk9OVFMpKQoJZ290byBiYWlsMTsKICAgIHJldHVybiBjb25maWc7CgpiYWlsMToKICAgIEZjQ29uZmlnRGVzdHJveSAoY29uZmlnKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKaW50CkZjR2V0VmVyc2lvbiAodm9pZCkKewogICAgcmV0dXJuIEZDX1ZFUlNJT047Cn0KCi8qCiAqIExvYWQgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZXMKICovCkZjQ29uZmlnICoKRmNJbml0TG9hZENvbmZpZyAodm9pZCkKewogICAgRmNDb25maWcJKmNvbmZpZzsKICAgIAogICAgY29uZmlnID0gRmNDb25maWdDcmVhdGUgKCk7CiAgICBpZiAoIWNvbmZpZykKCXJldHVybiBGY0ZhbHNlOwogICAgCiAgICBpZiAoIUZjQ29uZmlnUGFyc2VBbmRMb2FkIChjb25maWcsIDAsIEZjVHJ1ZSkpCiAgICB7CglGY0NvbmZpZ0Rlc3Ryb3kgKGNvbmZpZyk7CglyZXR1cm4gRmNJbml0RmFsbGJhY2tDb25maWcgKCk7CiAgICB9CgogICAgcmV0dXJuIGNvbmZpZzsKfQoKLyoKICogTG9hZCB0aGUgY29uZmlndXJhdGlvbiBmaWxlcyBhbmQgc2NhbiBmb3IgYXZhaWxhYmxlIGZvbnRzCiAqLwpGY0NvbmZpZyAqCkZjSW5pdExvYWRDb25maWdBbmRGb250cyAodm9pZCkKewogICAgRmNDb25maWcJKmNvbmZpZyA9IEZjSW5pdExvYWRDb25maWcgKCk7CgogICAgaWYgKCFjb25maWcpCglyZXR1cm4gMDsKICAgIGlmICghRmNDb25maWdCdWlsZEZvbnRzIChjb25maWcpKQogICAgewoJRmNDb25maWdEZXN0cm95IChjb25maWcpOwoJcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gY29uZmlnOwp9CgovKgogKiBJbml0aWFsaXplIHRoZSBkZWZhdWx0IGxpYnJhcnkgY29uZmlndXJhdGlvbgogKi8KRmNCb29sCkZjSW5pdCAodm9pZCkKewogICAgRmNDb25maWcJKmNvbmZpZzsKCiAgICBpZiAoX2ZjQ29uZmlnKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIGNvbmZpZyA9IEZjSW5pdExvYWRDb25maWdBbmRGb250cyAoKTsKICAgIGlmICghY29uZmlnKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIEZjQ29uZmlnU2V0Q3VycmVudCAoY29uZmlnKTsKICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfTUVNT1JZKQoJRmNNZW1SZXBvcnQgKCk7CiAgICByZXR1cm4gRmNUcnVlOwp9CgovKgogKiBGcmVlIGFsbCBsaWJyYXJ5LWFsbG9jYXRlZCBkYXRhIHN0cnVjdHVyZXMuCiAqLwp2b2lkCkZjRmluaSAodm9pZCkKewogICAgaWYgKF9mY0NvbmZpZykKCUZjQ29uZmlnRGVzdHJveSAoX2ZjQ29uZmlnKTsKCiAgICBGY1BhdHRlcm5UaGF3QWxsICgpOwogICAgRmNDaGFyU2V0VGhhd0FsbCAoKTsKfQoKLyoKICogUmVyZWFkIHRoZSBjb25maWd1cmF0aW9uIGFuZCBhdmFpbGFibGUgZm9udCBsaXN0cwogKi8KRmNCb29sCkZjSW5pdFJlaW5pdGlhbGl6ZSAodm9pZCkKewogICAgRmNDb25maWcJKmNvbmZpZzsKCiAgICBjb25maWcgPSBGY0luaXRMb2FkQ29uZmlnQW5kRm9udHMgKCk7CiAgICBpZiAoIWNvbmZpZykKCXJldHVybiBGY0ZhbHNlOwogICAgRmNDb25maWdTZXRDdXJyZW50IChjb25maWcpOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjSW5pdEJyaW5nVXB0b0RhdGUgKHZvaWQpCnsKICAgIEZjQ29uZmlnCSpjb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CiAgICB0aW1lX3QJbm93OwoKICAgIC8qCiAgICAgKiByZXNjYW5JbnRlcnZhbCA9PSAwIGRpc2FibGVzIGF1dG9tYXRpYyB1cCB0byBkYXRlCiAgICAgKi8KICAgIGlmIChjb25maWctPnJlc2NhbkludGVydmFsID09IDApCglyZXR1cm4gRmNUcnVlOwogICAgLyoKICAgICAqIENoZWNrIG5vIG1vcmUgb2Z0ZW4gdGhhbiByZXNjYW5JbnRlcnZhbCBzZWNvbmRzCiAgICAgKi8KICAgIG5vdyA9IHRpbWUgKDApOwogICAgaWYgKGNvbmZpZy0+cmVzY2FuVGltZSArIGNvbmZpZy0+cmVzY2FuSW50ZXJ2YWwgLSBub3cgPiAwKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIC8qCiAgICAgKiBJZiB1cCB0byBkYXRlLCBkb24ndCByZWxvYWQgY29uZmlndXJhdGlvbgogICAgICovCiAgICBpZiAoRmNDb25maWdVcHRvRGF0ZSAoMCkpCglyZXR1cm4gRmNUcnVlOwogICAgcmV0dXJuIEZjSW5pdFJlaW5pdGlhbGl6ZSAoKTsKfQoKc3RhdGljIHN0cnVjdCB7CiAgICBjaGFyICAgICpuYW1lOwogICAgaW50CSAgICBhbGxvY19jb3VudDsKICAgIGludAkgICAgYWxsb2NfbWVtOwogICAgaW50CSAgICBmcmVlX2NvdW50OwogICAgaW50CSAgICBmcmVlX21lbTsKfSBGY0luVXNlW0ZDX01FTV9OVU1dID0gewogICAgeyAiY2hhcnNldCIgfSwKICAgIHsgImNoYXJsZWFmIiB9LAogICAgeyAiZm9udHNldCIgfSwKICAgIHsgImZvbnRwdHIiIH0sCiAgICB7ICJvYmplY3RzZXQiIH0sCiAgICB7ICJvYmplY3RwdHIiIH0sCiAgICB7ICJtYXRyaXgiIH0sCiAgICB7ICJwYXR0ZXJuIiB9LAogICAgeyAicGF0ZWx0IiB9LAogICAgeyAidmFsbGlzdCIgfSwKICAgIHsgInN1YnN0YXRlIiB9LAogICAgeyAic3RyaW5nIiB9LAogICAgeyAibGlzdGJ1Y2siIH0sCiAgICB7ICJzdHJzZXQiIH0sCiAgICB7ICJzdHJsaXN0IiB9LAogICAgeyAiY29uZmlnIiB9LAogICAgeyAibGFuZ3NldCIgfSwKICAgIHsgImF0b21pYyIgfSwKICAgIHsgImJsYW5rcyIgfSwKICAgIHsgImNhY2hlIiB9LAogICAgeyAic3RyYnVmIiB9LAogICAgeyAic3Vic3QiIH0sCiAgICB7ICJvYmplY3R0eXBlIiB9LAogICAgeyAiY29uc3RhbnQiIH0sCiAgICB7ICJ0ZXN0IiB9LAogICAgeyAiZXhwciIgfSwKICAgIHsgInZzdGFjayIgfSwKICAgIHsgImF0dHIiIH0sCiAgICB7ICJwc3RhY2siIH0sCn07CgpzdGF0aWMgaW50ICBGY0FsbG9jQ291bnQsIEZjQWxsb2NNZW07CnN0YXRpYyBpbnQgIEZjRnJlZUNvdW50LCBGY0ZyZWVNZW07CgpzdGF0aWMgaW50ICBGY01lbU5vdGljZSA9IDEqMTAyNCoxMDI0OwoKc3RhdGljIGludCAgRmNBbGxvY05vdGlmeSwgRmNGcmVlTm90aWZ5OwoKdm9pZApGY1ZhbHVlTGlzdFJlcG9ydCAodm9pZCk7Cgp2b2lkCkZjTWVtUmVwb3J0ICh2b2lkKQp7CiAgICBpbnQJaTsKICAgIHByaW50ZiAoIkZjIE1lbW9yeSBVc2FnZTpcbiIpOwogICAgcHJpbnRmICgiXHQgICBXaGljaCAgICAgICBBbGxvYyAgICAgICAgICAgRnJlZSAgICAgICAgICAgQWN0aXZlXG4iKTsKICAgIHByaW50ZiAoIlx0ICAgICAgICAgICBjb3VudCAgIGJ5dGVzICAgY291bnQgICBieXRlcyAgIGNvdW50ICAgYnl0ZXNcbiIpOwogICAgZm9yIChpID0gMDsgaSA8IEZDX01FTV9OVU07IGkrKykKCXByaW50ZiAoIlx0JTguOHMlOGQlOGQlOGQlOGQlOGQlOGRcbiIsCgkJRmNJblVzZVtpXS5uYW1lLAoJCUZjSW5Vc2VbaV0uYWxsb2NfY291bnQsIEZjSW5Vc2VbaV0uYWxsb2NfbWVtLAoJCUZjSW5Vc2VbaV0uZnJlZV9jb3VudCwgRmNJblVzZVtpXS5mcmVlX21lbSwKCQlGY0luVXNlW2ldLmFsbG9jX2NvdW50IC0gRmNJblVzZVtpXS5mcmVlX2NvdW50LAoJCUZjSW5Vc2VbaV0uYWxsb2NfbWVtIC0gRmNJblVzZVtpXS5mcmVlX21lbSk7CiAgICBwcmludGYgKCJcdCU4LjhzJThkJThkJThkJThkJThkJThkXG4iLAoJICAgICJUb3RhbCIsCgkgICAgRmNBbGxvY0NvdW50LCBGY0FsbG9jTWVtLAoJICAgIEZjRnJlZUNvdW50LCBGY0ZyZWVNZW0sCgkgICAgRmNBbGxvY0NvdW50IC0gRmNGcmVlQ291bnQsCgkgICAgRmNBbGxvY01lbSAtIEZjRnJlZU1lbSk7CiAgICBGY0FsbG9jTm90aWZ5ID0gMDsKICAgIEZjRnJlZU5vdGlmeSA9IDA7CiAgICBGY1ZhbHVlTGlzdFJlcG9ydCAoKTsKfQoKdm9pZApGY01lbUFsbG9jIChpbnQga2luZCwgaW50IHNpemUpCnsKICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfTUVNT1JZKQogICAgewoJRmNJblVzZVtraW5kXS5hbGxvY19jb3VudCsrOwoJRmNJblVzZVtraW5kXS5hbGxvY19tZW0gKz0gc2l6ZTsKCUZjQWxsb2NDb3VudCsrOwoJRmNBbGxvY01lbSArPSBzaXplOwoJRmNBbGxvY05vdGlmeSArPSBzaXplOwoJaWYgKEZjQWxsb2NOb3RpZnkgPiBGY01lbU5vdGljZSkKCSAgICBGY01lbVJlcG9ydCAoKTsKICAgIH0KfQoKdm9pZApGY01lbUZyZWUgKGludCBraW5kLCBpbnQgc2l6ZSkKewogICAgaWYgKEZjRGVidWcoKSAmIEZDX0RCR19NRU1PUlkpCiAgICB7CglGY0luVXNlW2tpbmRdLmZyZWVfY291bnQrKzsKCUZjSW5Vc2Vba2luZF0uZnJlZV9tZW0gKz0gc2l6ZTsKCUZjRnJlZUNvdW50Kys7CglGY0ZyZWVNZW0gKz0gc2l6ZTsKCUZjRnJlZU5vdGlmeSArPSBzaXplOwoJaWYgKEZjRnJlZU5vdGlmeSA+IEZjTWVtTm90aWNlKQoJICAgIEZjTWVtUmVwb3J0ICgpOwogICAgfQp9Cg==