LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2xhbmcuYyx2IDEuMyAyMDAyLzA3LzA4IDA3OjMxOjUzIGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAyIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKCnR5cGVkZWYgc3RydWN0IHsKICAgIEZjQ2hhcjgJKmxhbmc7CiAgICBGY0NoYXJTZXQJY2hhcnNldDsKfSBGY0xhbmdDaGFyU2V0OwoKI2luY2x1ZGUgIi4uL2ZjLWxhbmcvZmNsYW5nLmgiCgojZGVmaW5lIE5VTV9MQU5HX0NIQVJfU0VUCShzaXplb2YgKGZjTGFuZ0NoYXJTZXRzKSAvIHNpemVvZiAoZmNMYW5nQ2hhclNldHNbMF0pKQoJCQkJCQkgCkZjQm9vbApGY0ZyZWVUeXBlU2V0TGFuZyAoRmNQYXR0ZXJuCSAgICAqcGF0dGVybiwgCgkJICAgRmNDaGFyU2V0CSAgICAqY2hhcnNldCwgCgkJICAgY29uc3QgRmNDaGFyOCAgICAqZXhjbHVzaXZlTGFuZykKewogICAgaW50CQkgICAgaTsKICAgIEZjQ2hhcjMyCSAgICBtaXNzaW5nOwogICAgRmNCb29sCSAgICBoYXNMYW5nID0gRmNGYWxzZTsKICAgIGNvbnN0IEZjQ2hhclNldCAqZXhjbHVzaXZlQ2hhcnNldCA9IDA7CgogICAgaWYgKGV4Y2x1c2l2ZUxhbmcpCglleGNsdXNpdmVDaGFyc2V0ID0gRmNDaGFyU2V0Rm9yTGFuZyAoZXhjbHVzaXZlTGFuZyk7CiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX0xBTkdfQ0hBUl9TRVQ7IGkrKykKICAgIHsKCS8qCgkgKiBDaGVjayBmb3IgSGFuIGNoYXJzZXRzIHRvIG1ha2UgZm9udHMKCSAqIHdoaWNoIGFkdmVydGlzZSBzdXBwb3J0IGZvciBhIHNpbmdsZSBsYW5ndWFnZQoJICogbm90IHN1cHBvcnQgb3RoZXIgSGFuIGxhbmd1YWdlcwoJICovCglpZiAoZXhjbHVzaXZlQ2hhcnNldCAmJgoJICAgIEZjRnJlZVR5cGVJc0V4Y2x1c2l2ZUxhbmcgKGZjTGFuZ0NoYXJTZXRzW2ldLmxhbmcpICYmCgkgICAgZmNMYW5nQ2hhclNldHNbaV0uY2hhcnNldC5sZWF2ZXMgIT0gZXhjbHVzaXZlQ2hhcnNldC0+bGVhdmVzKQoJewoJICAgIGNvbnRpbnVlOwoJfQoJbWlzc2luZyA9IEZjQ2hhclNldFN1YnRyYWN0Q291bnQgKCZmY0xhbmdDaGFyU2V0c1tpXS5jaGFyc2V0LCBjaGFyc2V0KTsKICAgICAgICBpZiAoRmNEZWJ1ZygpICYgRkNfREJHX1NDQU5WKQoJewoJICAgIGlmIChtaXNzaW5nICYmIG1pc3NpbmcgPCAxMCkKCSAgICB7CgkJRmNDaGFyU2V0ICAgKm1pc3NlZCA9IEZjQ2hhclNldFN1YnRyYWN0ICgmZmNMYW5nQ2hhclNldHNbaV0uY2hhcnNldCwgCgkJCQkJCQkgY2hhcnNldCk7CgkJRmNDaGFyMzIgICAgdWNzNDsKCQlGY0NoYXIzMiAgICBtYXBbRkNfQ0hBUlNFVF9NQVBfU0laRV07CgkJRmNDaGFyMzIgICAgbmV4dDsKCgkJcHJpbnRmICgiXG4lcyglZCkgIiwgZmNMYW5nQ2hhclNldHNbaV0ubGFuZywgbWlzc2luZyk7CgkJcHJpbnRmICgieyIpOwoJCWZvciAodWNzNCA9IEZjQ2hhclNldEZpcnN0UGFnZSAobWlzc2VkLCBtYXAsICZuZXh0KTsKCQkgICAgIHVjczQgIT0gRkNfQ0hBUlNFVF9ET05FOwoJCSAgICAgdWNzNCA9IEZjQ2hhclNldE5leHRQYWdlIChtaXNzZWQsIG1hcCwgJm5leHQpKQoJCXsKCQkgICAgaW50CSAgICBpLCBqOwoJCSAgICBmb3IgKGkgPSAwOyBpIDwgRkNfQ0hBUlNFVF9NQVBfU0laRTsgaSsrKQoJCQlpZiAobWFwW2ldKQoJCQl7CgkJCSAgICBmb3IgKGogPSAwOyBqIDwgMzI7IGorKykKCQkJCWlmIChtYXBbaV0gJiAoMSA8PCBqKSkKCQkJCSAgICBwcmludGYgKCIgJTA0eCIsIHVjczQgKyBpICogMzIgKyBqKTsKCQkJfQoJCX0KCQlwcmludGYgKCIgfVxuXHQiKTsKCQlGY0NoYXJTZXREZXN0cm95IChtaXNzZWQpOwoJICAgIH0KCSAgICBlbHNlCgkJcHJpbnRmICgiJXMoJWQpICIsIGZjTGFuZ0NoYXJTZXRzW2ldLmxhbmcsIG1pc3NpbmcpOwoJfQoJaWYgKCFtaXNzaW5nKQoJewoJICAgIGlmICghRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXR0ZXJuLCBGQ19MQU5HLCBmY0xhbmdDaGFyU2V0c1tpXS5sYW5nKSkKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICBoYXNMYW5nID0gRmNUcnVlOwoJfQogICAgfQogICAgLyoKICAgICAqIE1ha2Ugc3VyZSBpdCBoYXMgYSBsYW5nIGVudHJ5CiAgICAgKi8KICAgIGlmICghaGFzTGFuZykKCWlmICghRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXR0ZXJuLCBGQ19MQU5HLCAoRmNDaGFyOCAqKSAieC11bmtub3duIikpCgkgICAgcmV0dXJuIEZjRmFsc2U7CgogICAgaWYgKEZjRGVidWcoKSAmIEZDX0RCR19TQ0FOVikKCXByaW50ZiAoIlxuIik7CiAgICByZXR1cm4gRmNUcnVlOwp9CgoKRmNMYW5nUmVzdWx0CkZjTGFuZ0NvbXBhcmUgKGNvbnN0IEZjQ2hhcjggKnMxLCBjb25zdCBGY0NoYXI4ICpzMikKewogICAgY29uc3QgRmNDaGFyOCAgICpvcmlnX3MxID0gczE7CiAgICBGY0NoYXI4CSAgICBjMSwgYzI7CiAgICBGY0xhbmdSZXN1bHQgICAgcmVzdWx0OwogICAgLyoKICAgICAqIENvbXBhcmUgSVNPIDYzOSBsYW5ndWFnZSBjb2RlcwogICAgICovCiAgICBmb3IgKDs7KQogICAgewoJYzEgPSAqczErKzsKCWMyID0gKnMyKys7CglpZiAoYzEgPT0gJ1wwJyB8fCBjMSA9PSAnLScpCgkgICAgYnJlYWs7CglpZiAoYzIgPT0gJ1wwJyB8fCBjMiA9PSAnLScpCgkgICAgYnJlYWs7CgljMSA9IEZjVG9Mb3dlciAoYzEpOwoJYzIgPSBGY1RvTG93ZXIgKGMyKTsKCWlmIChjMSAhPSBjMikKCSAgICByZXR1cm4gRmNMYW5nRGlmZmVyZW50TGFuZzsJICAgIC8qIG1pc21hdGNoaW5nIGxhbmcgY29kZSAqLwogICAgfQogICAgaWYgKCFjMSAmJiAhYzIpCglyZXR1cm4gRmNMYW5nRXF1YWw7CiAgICAvKgogICAgICogTWFrZSB4LSogbWlzbWF0Y2ggYXMgaWYgdGhlIGxhbmcgcGFydCBkaWRuJ3QgbWF0Y2gKICAgICAqLwogICAgcmVzdWx0ID0gRmNMYW5nRGlmZmVyZW50Q291bnRyeTsKICAgIGlmIChvcmlnX3MxWzBdID09ICd4JyAmJiAob3JpZ19zMVsxXSA9PSAnXDAnIHx8IG9yaWdfczFbMV0gPT0gJy0nKSkKCXJlc3VsdCA9IEZjTGFuZ0RpZmZlcmVudExhbmc7CiAgICAKICAgIGlmIChjMSA9PSAnXDAnIHx8IGMyID09ICdcMCcpCglyZXR1cm4gcmVzdWx0OwogICAgLyoKICAgICAqIENvbXBhcmUgSVNPIDMxNjYgY291bnRyeSBjb2RlcwogICAgICovCiAgICBmb3IgKDs7KQogICAgewoJYzEgPSAqczErKzsKCWMyID0gKnMyKys7CglpZiAoIWMxIHx8ICFjMikKCSAgICBicmVhazsKCWMxID0gRmNUb0xvd2VyIChjMSk7CgljMiA9IEZjVG9Mb3dlciAoYzIpOwoJaWYgKGMxICE9IGMyKQoJICAgIGJyZWFrOwogICAgfQogICAgaWYgKGMxID09IGMyKQoJcmV0dXJuIEZjTGFuZ0VxdWFsOwogICAgZWxzZQoJcmV0dXJuIHJlc3VsdDsKfQoKY29uc3QgRmNDaGFyU2V0ICoKRmNDaGFyU2V0Rm9yTGFuZyAoY29uc3QgRmNDaGFyOCAqbGFuZykKewogICAgaW50CQlpOwogICAgaW50CQljb3VudHJ5ID0gLTE7CiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX0xBTkdfQ0hBUl9TRVQ7IGkrKykKICAgIHsKCXN3aXRjaCAoRmNMYW5nQ29tcGFyZSAobGFuZywgZmNMYW5nQ2hhclNldHNbaV0ubGFuZykpIHsKCWNhc2UgRmNMYW5nRXF1YWw6CgkgICAgcmV0dXJuICZmY0xhbmdDaGFyU2V0c1tpXS5jaGFyc2V0OwoJY2FzZSBGY0xhbmdEaWZmZXJlbnRDb3VudHJ5OgoJICAgIGlmIChjb3VudHJ5ID09IC0xKQoJCWNvdW50cnkgPSBpOwoJZGVmYXVsdDoKCSAgICBicmVhazsKCX0KICAgIH0KICAgIGlmIChjb3VudHJ5ID09IC0xKQoJcmV0dXJuIDA7CiAgICByZXR1cm4gJmZjTGFuZ0NoYXJTZXRzW2ldLmNoYXJzZXQ7Cn0K